<!doctype html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <meta name="full-screen" content="true"/>
    <meta name="screen-orientation" content="portrait"/>
    <meta name="x5-fullscreen" content="true"/>
    <meta name="360-fullscreen" content="true"/>
    <title>Setup Tab-OS</title>
    <style>
        body {
            font-family: arial;
            -ms-touch-action: none;
            background: #FFFFFF;
            border: 0;
            margin: 0;
            height: 100%;
        }

        .cody { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
        div.cody {
            text-align: center;
            border: 0;
            margin: 0;
            height: 100%;
        }
        div.cody_border {
            border: 0;
            -webkit-tap-highlight-color: transparent;
            height: 500px;
            width: 100%;
        }
    </style>
</head>
<body style="overflow: hidden">
<div class="cody_border" id="JAXAppFrame">
</div>
<input type="file" id="JAXFileInput" style="opacity: 0; position: absolute; top: -100px"/>
<a id="JAXFileDownload" href="" style="opacity: 0; position: absolute; top: -100px"> </a>
<script type="module">
	class JAXDiskSysStore {
	constructor() {
		let dbName,storeName;
		dbName="CokeCodes";
		storeName="System";
		this.storeName = storeName;
		this._dbp = new Promise((resolve, reject) => {
			const openreq = indexedDB.open(dbName, 1);
			openreq.onerror = () => reject(openreq.error);
			openreq.onsuccess = () => resolve(openreq.result);
			// First time setup: create an empty object store
			openreq.onupgradeneeded = () => {
				openreq.result.createObjectStore(storeName);
			};
		});
	}
	_withIDBStore(type, callback) {
		return this._dbp.then(db => new Promise((resolve, reject) => {
			const transaction = db.transaction(this.storeName, type);
			transaction.oncomplete = () => resolve();
			transaction.onabort = transaction.onerror = () => reject(transaction.error);
			callback(transaction.objectStore(this.storeName));
		}));
	}
}
let sysStore=null;

class JAXDiskStore {
	constructor(diskName, storeName = null) {
		let dbName;
		dbName="Disk_"+diskName;
		this.dbName=dbName;
		storeName=storeName||diskName;
		if(storeName!==diskName && storeName!=="info" && storeName!=="base"){
			throw Error("JAXDiskStore: Store name error: "+storeName);
		}
		this.storeName = storeName;
		this._dbp = new Promise((resolve, reject) => {
			const openreq = indexedDB.open(dbName, 1);
			openreq.onerror = () => reject(openreq.error);
			openreq.onsuccess = () => resolve(openreq.result);
			// First time setup: create an empty object store
			openreq.onupgradeneeded = () => {
				openreq.result.createObjectStore(diskName);
				openreq.result.createObjectStore("info");
				openreq.result.createObjectStore("base");
			};
		});
	}
	_withIDBStore(type, callback) {
		return this._dbp.then(db => new Promise((resolve, reject) => {
			const transaction = db.transaction(this.storeName, type);
			transaction.oncomplete = () => resolve();
			transaction.onabort = transaction.onerror = () => reject(transaction.error);
			callback(transaction.objectStore(this.storeName));
		}));
	}
	static systemStore(){
		if(sysStore){
			return sysStore;
		}
		sysStore=new JAXDiskSysStore();
		return sysStore;
	}
}

function get(key, store) {
	let req;
	return store._withIDBStore('readonly', store => {
		req = store.get(key);
	}).then(() => req.result);
}
function set(key, value, store) {
	return store._withIDBStore('readwrite', store => {
		store.put(value, key);
	});
}
function del(key, store) {
	return store._withIDBStore('readwrite', store => {
		store.delete(key);
	});
}
function clear(store) {
	return store._withIDBStore('readwrite', store => {
		store.clear();
	});
}
function keys(store) {
	const keys = [];
	return store._withIDBStore('readonly', store => {
		// This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
		// And openKeyCursor isn't supported by Safari.
		(store.openKeyCursor || store.openCursor).call(store).onsuccess = function () {
			if (!this.result)
				return;
			keys.push(this.result.key);
			this.result.continue();
		};
	}).then(() => keys);
}

function drop(databaseName){
	indexedDB.deleteDatabase(databaseName);
}
let DiskStore=JAXDiskStore;

//****************************************************************************
//Utility functions:
//****************************************************************************
let pathLib$1,digestBytes,divPath;
{
	pathLib$1={
		join:function(path1,path2){
			if(path1==="/"){
				return path1+path2;
			}
			if(!path1){
				return path2;
			}
			while(path1.endsWith("/")){
				path1=path1.substring(0,path1.length-1);
			}
			while(path2.startsWith("/")){
				path2=path2.substring(1);
			}
			return path1+"/"+path2
		},
		extname:function(path){
			let pos;
			pos=path.lastIndexOf(".");
			if(pos>=0){
				return path.substring(pos);
			}
			return "";
		}
	};
	
	//------------------------------------------------------------------------
	digestBytes=async function(buf){
		let hex;
		const hashBuffer = await crypto.subtle.digest('SHA-256', buf);       	    	// hash the message
		const hashArray = Array.from(new Uint8Array(hashBuffer));                     			// convert buffer to byte array
		hex= hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
		return hex;
	};
	
	//------------------------------------------------------------------------
	divPath=function(dirPath){
		let pos,dirName,upPath;
		//Split dir upper and base:
		if(dirPath.endsWith("/")){
			dirPath=dirPath.substring(0,dirPath.length-1);
		}
		pos=dirPath.lastIndexOf("/");
		if(pos>=0){
			dirName=dirPath.substring(pos+1);
			upPath=dirPath.substring(0,pos);
		}else {
			dirName=dirPath;
			upPath="";
		}
		if(upPath.startsWith("/")){
			upPath=upPath.substring(1);
		}
		return [dirName,upPath];
	};
}

var JAXDisk$1,jaxDisk;
var JAXMemDisk,jaxMemDisk;
let notifyModifyAct;

//****************************************************************************
//JAX's virtual disk system for web
//****************************************************************************
JAXDisk$1=function(diskName,majorDisk=null,code="")
{
	this.name=diskName;
	//this.dbStore=new Store('JAXDisk_'+diskName, code?(code+"@"+diskName):diskName);
	this.dbStore=new JAXDiskStore(diskName);
	this.writeObj=null;
	this.writeVsn=0;
	if(majorDisk){
		majorDisk.subDisk[code]=this;
	}else {
		JAXDisk$1.diskHash[diskName] = this;
		this.subDisk={};
	}
	this.refCount=1;
	this.infoStore=new JAXDiskStore(diskName, "info");
	this.baseStore=new JAXDiskStore(diskName, "base");
	this.inMemory=false;
	this.memDisk=null;
	this.syncAcessPms=null;
};
jaxDisk=JAXDisk$1.prototype={};

//----------------------------------------------------------------------------
//All available disk:
//JAXDisk.sysStore=new Store('JAXDisk_', "System");
JAXDisk$1.sysStore=JAXDiskStore.systemStore();
JAXDisk$1.disks=null;
JAXDisk$1.diskHash={};

//****************************************************************************
//JAXDisk static-system functions:
//****************************************************************************
{
	//---------------------------------------------------------------------------
	//Init jax-disk system.
	JAXDisk$1.init=async function(_swClient,refresh=false) {
		let list;
		if(JAXDisk$1.disks && !refresh){
			return;
		}
		list=await get("disks",JAXDisk$1.sysStore);
		if (Array.isArray(list)) {
			//list.push("books");
			JAXDisk$1.disks = new Set(list);
		} else {
			JAXDisk$1.disks = new Set();
			set("disks", [], JAXDisk$1.sysStore).then(() => {
			});
		}
	};
	
	//------------------------------------------------------------------------
	JAXDisk$1.checkDisks=async function(){
		let list,name,disk,disks,needSync,entry;
		
		let deleteDisk=(name)=>{
			console.log("CheckDisk: delete disk: "+name);
			disks.delete(name);
			delete this.diskHash[name];
			needSync=true;
		};
		
		needSync=false;
		disks=this.disks;
		/*list=await get("disks", JAXDisk.sysStore);
		if(!Array.isArray(list)){
			return;
		}*/
		for(name of disks){
			try{
				//console.log("CheckDisk: "+name);
				disk=await this.openDisk(name,false);
				if(!disk){
					deleteDisk(name);
				}else {
					entry=await get(".",disk.dbStore);
					if(!entry){
						deleteDisk(name);
					}
				}
			}catch(err){
				deleteDisk(name);
			}
		}
		if(indexedDB.databases){
			let stub,store,rootObj;
			list=await indexedDB.databases();
			for(stub of list){
				//console.log("Check DB: ",stub);
				name=stub.name;
				if(name && name.startsWith("Disk_")){
					name=name.substring("Disk_".length);
					store=new JAXDiskStore(name);
					rootObj=await get(".",store);
					if(rootObj && typeof(rootObj)==="object"){
						//TODO: Add this disk:
						if(!disks.has(name)){
							needSync=true;
							disks.add(name);
							console.log("CheckDisk: resotre disk: "+name);
						}
					}
				}
			}
		}
		if(needSync){
			await set('disks', Array.from(disks), this.sysStore);
		}
		console.log("Check disk: done.");
	};
	
	//------------------------------------------------------------------------
	JAXDisk$1.syncDiskSet=async function(){
		let list,name,disks;
		list=await get("disks", JAXDisk$1.sysStore);
		if(!Array.isArray(list)){
			return;
		}
		disks=JAXDisk$1.disks;
		for(name of list){
			if(!disks.has(name)){
				disks.add(name);
			}
		}
	};
	
	//---------------------------------------------------------------------------
	//Open an disk, may create new disk if param create is true:
	JAXDisk$1.openDisk = async function (diskName, create) {
		let disk;
		if(!this.disks) {
			await this.init();
		}
		disk = this.diskHash[diskName];
		if (disk) {
			//Check if the disk is still there:
			try {
				let list = await get("disks", JAXDisk$1.sysStore);
				if (list.indexOf(diskName) >= 0) {
					disk.refCount++;
					return disk;
				} else {
					//The disk is removed.
					this.disks.delete(diskName);
					delete this.diskHash[diskName];
					if(create){
						return await JAXDisk$1.newDisk(diskName);
					}
					return null;
				}
			}catch(err) {
				return null;
			}
		}
		if (!this.disks.has(diskName)) {
			let list=await get("disks",JAXDisk$1.sysStore);
			if(list && list.indexOf(diskName)>=0){
				this.disks.add(diskName);
				return new JAXDisk$1(diskName);
			}
			if (create) {
				return await JAXDisk$1.newDisk(diskName);
			}
			return null;
		}//else:
		let list=await get("disks",JAXDisk$1.sysStore);
		if(list && list.indexOf(diskName)>=0) {
			return new JAXDisk$1(diskName);
		}
		//The disk is removed.
		this.disks.delete(diskName);
		delete this.diskHash[diskName];
		return null;
	};
	
	//---------------------------------------------------------------------------
	//Check if a disk is exist:
	JAXDisk$1.diskExist = function (diskName,doubleCheck=0) {
		var self=this;
		return new Promise((resolve, reject) => {
			if (self.disks.has(diskName)) {
				resolve(1);
			} else {
				if(doubleCheck){
					//Check again with DB:
					return get("disks",JAXDisk$1.sysStore).then(list=>{
						if(list.indexOf(diskName)>=0){
							JAXDisk$1.disks.add(diskName);
							resolve(1);
						}else {
							resolve(0);
						}
					});
				}else {
					resolve(0);
				}
			}
		});
	};
	
	//---------------------------------------------------------------------------
	//Create a new disk:
	JAXDisk$1.newDisk = async function (diskName) {
		let self=this,diskObj,store,rootObj;
		if(diskName.indexOf("/")>=0 || diskName.indexOf("*")>=0){
			throw new Error("New disk: illegal name.");
		}
		await JAXDisk$1.syncDiskSet();
		if (self.disks.has(diskName)) {
			diskObj=await self.openDisk(diskName,0);
			if(diskObj){
				return diskObj;
			}
		}
		self.disks.add(diskName);
		await set('disks', Array.from(self.disks), self.sysStore);
		store=new JAXDiskStore(diskName);
		rootObj=await get(".",store);
		if(!rootObj || typeof(rootObj)!=="object"){
			await set(".",{},store);
		}
		diskObj=new JAXDisk$1(diskName);
		return diskObj;
	};
	
	//---------------------------------------------------------------------------
	//Get a disk's info VO:
	JAXDisk$1.getDiskInfo=async function(diskName){
		let disk,infoStore;
		if(!this.disks) {
			await this.init();
		}
		disk=await this.openDisk(diskName,false);
		if(!disk){
			return null;
		}
		infoStore=disk.infoStore;
		if(!infoStore){
			//disk.infoStore=infoStore=new Store('JAXDiskInfo_'+diskName, diskName,1);
			disk.infoStore=infoStore=new JAXDiskStore(diskName, "info");
		}
		return await get("info",infoStore);
	};
	
	//---------------------------------------------------------------------------
	//Set a disk's info VO:
	JAXDisk$1.setDiskInfo=async function(diskName,info){
		let disk,infoStore,pms;
		if(!this.disks) {
			await this.init();
		}
		disk=await this.openDisk(diskName);
		if(!disk){
			return null;
		}
		infoStore=disk.infoStore;
		if(!infoStore){
			//disk.infoStore=infoStore=new Store('JAXDiskInfo_'+diskName, diskName,1);
			disk.infoStore=infoStore=new JAXDiskStore(diskName, "info");
			await set("info",info,infoStore);
			return;
		}
		if(disk.writeObj){
			await disk.writeObj;
		}
		pms=set("info",info,infoStore);
		disk.writeObj=pms;
		pms.writeVsn=disk.writeVsn++;
		return pms;
	};
	
	//---------------------------------------------------------------------------
	//Get a disk's info VO:
	JAXDisk$1.getDiskAttr=async function(diskName,attr){
		let disk,infoStore;
		if(!this.disks) {
			await this.init();
		}
		disk=await this.openDisk(diskName,false);
		if(!disk){
			return null;
		}
		infoStore=disk.infoStore;
		if(!infoStore){
			disk.infoStore=infoStore=new JAXDiskStore(diskName, "info");
		}
		return await get("attr_"+attr,infoStore);
	};
	
	//---------------------------------------------------------------------------
	//Set a disk's attr:
	JAXDisk$1.setDiskAttr=async function(diskName,key,val){
		let disk,infoStore,pms;
		if(!this.disks) {
			await this.init();
		}
		disk=await this.openDisk(diskName);
		if(!disk){
			return null;
		}
		infoStore=disk.infoStore;
		if(!infoStore){
			disk.infoStore=infoStore=new JAXDiskStore(diskName, "info");
			await set("attr_"+key,val,infoStore);
			return;
		}
		if(disk.writeObj){
			await disk.writeObj;
		}
		pms=set("attr_"+key,val,infoStore);
		disk.writeObj=pms;
		pms.writeVsn=disk.writeVsn++;
		return pms;
	};
	
	//---------------------------------------------------------------------------
	//Remove a disk, clear the DB(but not drop the db)
	JAXDisk$1.dropDisk = async function (diskName,dropDB=false) {
		let self,diskObj;
		self=this;
		diskObj=await self.openDisk(diskName,false);
		if(diskObj){
			try {
				if (diskObj.dbStore) {
					await clear(diskObj.dbStore);
					if (diskObj.infoStore) {
						await clear(diskObj.infoStore);
					}
					if (diskObj.baseStore) {
						await clear(diskObj.baseStore);
					}
				}
			}catch(err){
				console.log(`Drop disk ${diskName} error: ${err}`);
				return false;
			}
		}else {
			return false;
		}
		await self.syncDiskSet();
		self.disks.delete(diskName);
		delete self.diskHash[diskName];
		await set('disks', Array.from(self.disks), self.sysStore);
		if(dropDB){
			drop(diskObj.dbStore.dbName);
		}
		return true;
	};
	
	//---------------------------------------------------------------------------
	//Get current disks list:
	JAXDisk$1.getDisks=function(sync=false){
		if(sync){
			JAXDisk$1.syncDiskSet();
		}
		return Array.from(this.disks);
	};
	
	//---------------------------------------------------------------------------
	//Get current disk names
	JAXDisk$1.getDiskNames=async function(sync=false){
		let list,i,n,name,disk;
		await this.init(true);
		list=Array.from((this.disks));
		n=list.length;
		for(i=0;i<n;i++){
			name=list[i];
			disk=await JAXDisk$1.openDisk(name,0);
			if(!disk){
				list.splice(i,1);
				JAXDisk$1.disks.delete(name);
				delete JAXDisk$1.diskHash[name];
				n--;i--;
			}
		}
		return list;
	};
	
	//---------------------------------------------------------------------------
	//Make a disk in-memory so can sync accessed
	JAXDisk$1.syncDisk=async function(diskName,create=false){
		let disk;
		disk=await JAXDisk$1.openDisk(diskName,create);
		if(!disk)
			return false;
		if(disk.memDisk){
			await disk.syncAcessPms;
			return true;
		}
		return await disk.syncAccess();
	};
	
	//---------------------------------------------------------------------------
	//Get package path's real path:
	JAXDisk$1.getPkgPath=async function(pkgPath){
		let pkgName,path,pos,pkgJSON,pkgRoot;
		if(!pkgPath.startsWith("/@")){
			throw new Error(`${pkgPath} is not a packages path (starts with "/@").`);
		}
		pos=pkgPath.indexOf("/",2);
		if(pos>0){
			pkgName=pkgPath.substring(2,pos);
			path=pkgPath.substring(pos+1);
		}else {
			pkgName=pkgPath.substring(2);
			path="";
		}
		try {
			pkgJSON = await JAXDisk$1.readFile(`/coke/lib/${pkgName}.json`, "utf8");
			pkgJSON=JSON.parse(pkgJSON);
			pkgRoot=pkgJSON.path;
			if(!path){
				return pkgRoot;
			}
			return pathLib$1.join(pkgRoot,path);
		}catch(err){
			throw new Error(`${pkgName} is not a installed pkg`);
		}
	};
	
	//-----------------------------------------------------------------------
	//Get package's main entry absolute-path:
	JAXDisk$1.getPkgMain=async function(pkgName){
		try {
			let pkgJSON;
			pkgJSON = await JAXDisk$1.readFile(`/coke/lib/${pkgName}.json`, "utf8");
			pkgJSON=JSON.parse(pkgJSON);
			return pkgJSON.main;
		}catch(err){
			throw new Error(`${pkgName} is not a installed pkg`);
		}
	};
}

//****************************************************************************
//JAXDisk member functions
//****************************************************************************
{
	//-----------------------------------------------------------------------
	//Upgrade a disk for sync access:
	jaxDisk.syncAccess=async function(){
		let memDisk;
		if(this.memDisk) {
			await this.syncAcessPms;
			return true;
		}
		memDisk=new JAXMemDisk(this);
		this.memDisk=memDisk;
		this.syncAcessPms=memDisk.init();
		await this.syncAcessPms;
		return true;
	};
	
	jaxDisk.newDir=async function(dirPath,allowRoot=0,recursive=true){
		var self=this;
		let writeVsn,actorId;
		if(typeof(allowRoot)==="object"){
			let opts=allowRoot;
			allowRoot=opts.allowRoot||false;
			recursive=opts.recursive||true;
			actorId=opts.actor||null;
		}else {
			actorId=null;
		}
		if(dirPath==='.'){
			if(!allowRoot) {
				throw "Error: '.' is not allowed for folder name.";
			}
		}
		
		if(dirPath.endsWith("/")){
			dirPath=dirPath.substring(0,dirPath.length-1);
		}
		if(dirPath.startsWith("/")){
			dirPath=dirPath.substring(1);
		}
		
		async function mkDirList(list){
			let i,n,stub;
			n=list.length;
			for(i=0;i<n;i++) {
				stub=list[i];
				await set(stub.path, stub.obj,self.dbStore);
			}
			return list[0];
		}
		
		async function doNewDir() {
			if(self.writeObj && self.writeObj.writeVsn!==writeVsn){
				await self.writeObj;
			}
			
			return get(dirPath, self.dbStore).then(async curDirObj => {
				let upPath, dirName;
				let dirList;
				let time = Date.now();
				
				dirList=[];
				
				//Check if path is already there and if it's dir?
				if (curDirObj instanceof Uint8Array) {
					throw "Can't create dir on file!";
				} else if (typeof (curDirObj) === 'object') {
					return curDirObj;
				}
				
				//Path is empty, create dir:
				dirList.push({path:dirPath,obj:{}});
				[dirName, upPath] = divPath(dirPath);
				if(!upPath){
					upPath=".";
				}
				while(upPath){
					let dirObj;
					dirObj=await get(upPath, self.dbStore);
					if(!dirObj){
						if(!recursive){
							return null;
						}
						dirObj={};
						dirObj[dirName]={
							name: dirName, dir: 1, createTime: time, modifyTime: time,
						};
						dirList.push({path:upPath,obj:dirObj});
					}else {
						dirObj[dirName]={
							name: dirName, dir: 1, createTime: time, modifyTime: time,
						};
						dirList.push({path:upPath,obj:dirObj});
						break;
					}
					if(upPath==="."){
						throw "newDir: Bad disk structure!";
					}
					[dirName, upPath] = divPath(upPath);
					if(!upPath){
						upPath=".";
					}
				}
				await mkDirList(dirList);
				//Call cross-tab notify:
				notifyModifyAct("NewDir","/"+self.name+"/"+dirPath,actorId);
				return dirList[0].obj;
			})
		}
		//Sync write operation:
		writeVsn=this.writeVsn++;
		self.writeObj=doNewDir();
		self.writeObj.writeVsn=writeVsn;
		self.writeObj.path=dirPath;
		return self.writeObj;
	};
	
	//-----------------------------------------------------------------------
	//Delete an entry-item, if path is a dir, also delete the whole dir tree under it.
	jaxDisk.del=async function(path,opts=null){
		let self=this;
		let writeVsn,actorId,delPath;
		
		if(opts){
			actorId=opts.actor||null;
		}
		
		//console.log("Disk.del: "+path);
		if(path.endsWith("/")){
			path=path.substring(0,path.length-1);
		}
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(path.startsWith("./")){
			path=path.substring(2);
		}
		delPath=path;
		
		//-------------------------------------------------------------------
		//Delete file/dir item array(list)
		async function doDelList(list){
			let i,n,item,pList;
			n=list.length;
			pList=[];
			for(i=0;i<n;i++){
				item=list[i];
				pList.push(del(item,self.dbStore));//Delete one item
			}
			return Promise.allSettled(pList);
		}
		
		//-------------------------------------------------------------------
		//List an dir's all sub-tree items including sub in sub
		async function doMakeList(tgtPath,tgtList){
			let list,i,n,stub;
			tgtList.push(tgtPath);
			list=await self.getEntries(tgtPath);
			n=list.length;
			for(i=0;i<n;i++){
				stub=list[i];
				if(stub.dir){
					await doMakeList((tgtPath?(tgtPath+"/"+stub.name):stub.name),tgtList);
				}else {
					tgtList.push((tgtPath?(tgtPath+"/"+stub.name):stub.name));
				}
			}
		}
		
		//-------------------------------------------------------------------
		//Erase item's entry in upper dir record:
		async function doDelEntry(tgtPath){
			let tgtName,upPath;
			[tgtName,upPath]=divPath(tgtPath);
			if(!upPath){
				upPath=".";
			}
			return get(upPath,self.dbStore).then((upDirObj)=>{
				if(upDirObj){
					delete upDirObj[tgtName];
					return set(upPath,upDirObj,self.dbStore);
				}
			});
		}
		
		//-------------------------------------------------------------------
		//Check delete item type, exec the del operation:
		async function checkAndDel(){
			if(self.writeObj && self.writeObj.writeVsn!==writeVsn){
				self.writeObj.path;
				await self.writeObj;
			}
			
			return get(path,self.dbStore).then(async (delObj)=> {
				let delList;
				
				//Do the delete:
				delList=[];
				if(delObj instanceof Uint8Array) {
					//File, nothing more.
					delList.push(path);
					return doDelList(delList).then(()=>{
						return doDelEntry(path);
					});
				}else if(delObj){
					//Dir, generate the sub-item list to delete
					await doMakeList(path,delList);
					return doDelList(delList).then(()=>{
						return doDelEntry(path);
					});
				}else {
					return doDelEntry(path);
				}
			}).then(()=>{
				notifyModifyAct("Del","/"+self.name+"/"+delPath,actorId);
			});
		}
		writeVsn=this.writeVsn++;
		self.writeObj=checkAndDel();
		self.writeObj.writeVsn=writeVsn;
		self.writeObj.path=path;
		//console.log("Set wait obj: "+path);
		return self.writeObj;
	};
	
	//-----------------------------------------------------------------------
	//Save a file, fileObj can be string, File-Object, etc.
	jaxDisk.saveFile=function(path,fileObj,opts=null){
		let self,tgtName,upPath,byteAry,time,writeVsn,byteHex;
		let actorId,filepath,recursive=true;
		self=this;
		
		if(opts){
			actorId=opts.actor||null;
			recursive=opts.recursive||true;
		}
		
		//console.log("JAXDisk.saveFile: Disk.saveFile: "+path);
		if(path.endsWith("/")){
			throw "JAXDisk.saveFile: Error: filename can't end with '/'!";
		}
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		filepath=path;
		
		[tgtName,upPath]=divPath(path);
		time=Date.now();
		
		//Save byte content to DB, update entry info, make base backup if needed:
		async function saveByteAry(){
			let dirVO,stub,oldData,oldHash;
			//console.log("saveByteAry: "+path+", writeObj: "+(self.writeObj?self.writeObj.filePath:"null"));
			//wait for current update file:
			if(self.writeObj && self.writeObj.writeVsn!==writeVsn){
				await self.writeObj;
			}
			//get upper dirVO:
			dirVO=await get(upPath?upPath:".",self.dbStore);
			if(!dirVO){
				throw "Path is not available: "+upPath;
			}
			stub=dirVO[tgtName];
			if(stub){
				//file exists, update stub, save base if 1st :
				oldHash=stub.hash;
				stub.modifyTime=time;
				if(!stub.modified && (oldHash!==byteHex || stub.size!==byteAry.byteLength)) {
					oldData=await get(upPath ? (upPath + "/" + tgtName) : tgtName, self.dbStore);
					//save the base file content:
					if(oldData) {
						set(upPath ? (upPath + "/" + tgtName) : tgtName, oldData, self.baseStore);
					}
					stub.modified=true;
				}
				stub.size=byteAry.byteLength;
				stub.hash=byteHex;
				//update stub:
			}else {
				//new file, create stub:
				dirVO[tgtName]={
					name:tgtName,dir:0,createTime:time,modifyTime:time,size:byteAry.byteLength,modified:true,
					hash:byteHex
				};
			}
			await set(upPath?(upPath+"/"+tgtName):tgtName,byteAry,self.dbStore);
			await set(upPath?upPath:".",dirVO,self.dbStore);
			//Call cross-tab notify:
			notifyModifyAct("File","/"+self.name+"/"+filepath,actorId);
		}
		
		async function arrayBuffer(file){
			if(file.arrayBuffer){
				return file.arrayBuffer();
			}
			return new Promise((onDone,onError)=>{
				let reader=new FileReader();
				reader.onload=function(event) {
					let arrayBuffer = event.target.result;
					onDone(arrayBuffer);
				};
				reader.readAsArrayBuffer(file);
			})
		}
		
		function doCopy(){
			//Ensure saved object is ByteArray
			if (typeof (fileObj) === 'string') {
				let encoder = new TextEncoder();
				byteAry = encoder.encode(fileObj);
				return digestBytes(byteAry).then(hex=>{
					writeVsn = self.writeVsn++;
					byteHex=hex;
					self.writeObj =saveByteAry();
					self.writeObj.filePath = path;
					self.writeObj.writeVsn = writeVsn;
					return self.writeObj;
				});
			} else if (fileObj instanceof File) {
				return arrayBuffer(fileObj).then(async buf => {
					byteAry = new Uint8Array(buf);
					return digestBytes(byteAry).then(hex=>{
						writeVsn = self.writeVsn++;
						byteHex=hex;
						self.writeObj =saveByteAry();
						self.writeObj.filePath = path;
						self.writeObj.writeVsn = writeVsn;
						return self.writeObj;
					});
				});
			} else if (fileObj instanceof Uint8Array) {
				byteAry = fileObj;
				return digestBytes(byteAry).then(hex=>{
					writeVsn = self.writeVsn++;
					byteHex=hex;
					self.writeObj =saveByteAry();
					self.writeObj.filePath = path;
					self.writeObj.writeVsn = writeVsn;
					return self.writeObj;
				});
			}else if(fileObj instanceof ArrayBuffer){
				byteAry = new Uint8Array(fileObj);
				return digestBytes(byteAry).then(hex=>{
					writeVsn = self.writeVsn++;
					byteHex=hex;
					self.writeObj =saveByteAry();
					self.writeObj.filePath = path;
					self.writeObj.writeVsn = writeVsn;
					return self.writeObj;
				});
			}else if(fileObj.name && fileObj.size>=0){//work around: fileObj from page?
				return arrayBuffer(fileObj).then(async buf => {
					byteAry = new Uint8Array(buf);
					return digestBytes(byteAry).then(hex=>{
						writeVsn = self.writeVsn++;
						byteHex=hex;
						self.writeObj =saveByteAry();
						self.writeObj.filePath = path;
						self.writeObj.writeVsn = writeVsn;
						return self.writeObj;
					});
				});
			}else if(fileObj.buffer && fileObj.byteLength===fileObj.length && fileObj.length>=0){
				//work around of Uint8Array:
				byteAry = fileObj;
				return digestBytes(byteAry).then(hex=>{
					writeVsn = self.writeVsn++;
					byteHex=hex;
					self.writeObj =saveByteAry();
					self.writeObj.filePath = path;
					self.writeObj.writeVsn = writeVsn;
					return self.writeObj;
				});
			}else if(fileObj.byteLength>=0){
				byteAry = new Uint8Array(fileObj);
				return digestBytes(byteAry).then(hex=>{
					writeVsn = self.writeVsn++;
					byteHex=hex;
					self.writeObj =saveByteAry();
					self.writeObj.filePath = path;
					self.writeObj.writeVsn = writeVsn;
					return self.writeObj;
				});
			}
		}
		
		if(upPath){
			return get(upPath,self.dbStore).then(pathObj=>{
				//Ensure the target dir is there:
				if(pathObj) {
					if (pathObj instanceof Uint8Array) {
						//upPath is a file, can't go on:
						throw Error(`${upPath} is a file, can't write new file ${path} under it.`);
					}
					return doCopy();
				}else if(recursive){
					return self.newDir(upPath).then(()=>{
						return doCopy();
					});
				}
			});
		}else {
			return doCopy();
		}
	};
	
	//-----------------------------------------------------------------------
	//Load file data as ByteArray
	jaxDisk.loadFile=function(path){
		var self;
		self=this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		return get(path,self.dbStore).then(fileObj=>{
			if(fileObj instanceof Uint8Array){
				return fileObj;
			}
			return null;
		});
	};
	
	//-----------------------------------------------------------------------
	//Load file data as text
	jaxDisk.loadText=function(path){
		var self;
		self=this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		return get(path,self.dbStore).then(fileObj=>{
			if(fileObj instanceof Uint8Array){
				let enc = new TextDecoder("utf-8");
				return enc.decode(fileObj);
			}
			return null;
		}).catch(err=>{
			return null;
		});
	};
	
	//-----------------------------------------------------------------------
	//Write file, if encode!==null, read as text:
	jaxDisk.writeFile=function(path,obj,encode=null){
		let opts;
		if(path.startsWith("./")){
			path=path.substring(2);
		}
		if(encode && typeof(encode)==="object"){
			opts=encode;
			encode=opts.encode||null;
		}else {
			opts=null;
		}
		if(encode) {
			obj=""+obj;//Lazy convert
		}
		return this.saveFile(path,obj,opts);
	};
	
	//-----------------------------------------------------------------------
	//Read file, if encode!==null, read as text:
	jaxDisk.readFile=function(path,encode=null){
		if(encode) {
			return this.loadText(path);
		}else {
			return this.loadFile(path);
		}
	};
	
	//-----------------------------------------------------------------------
	//List sub-item-vo under path, return null if path is a file:
	jaxDisk.getEntries=function(path){
		var self;
		self=this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(!path){
			path='.';
		}
		return get(path,self.dbStore).then(fileObj=>{
			if(fileObj instanceof Uint8Array || !fileObj){
				return null;//this is file, not dir
			}
			return Object.values(fileObj);
		});
	};
	
	//-----------------------------------------------------------------------
	//Check if a path is existed:
	jaxDisk.isExist=function(path){
		var self=this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(!path){
			path='.';
		}
		return get(path,self.dbStore).then(fileObj=>{
			return !!fileObj;
		});
	};
	
	//-----------------------------------------------------------------------
	//Get item entry(info) by path
	jaxDisk.getEntry=async function(path){
		let self=this;
		let dir,fileName;
		[fileName,dir]=divPath(path);
		if(dir.startsWith("/")){
			dir=dir.substring(1);
		}
		if(dir.endsWith("/")){
			dir=dir.substring(0,dir.length-1);
		}
		if(!dir){
			dir='.';
			if(fileName===""){
				return {name:self.name,dir:1,disk:1};
			}
		}
		let dirObj=await get(dir,self.dbStore);
		if(dirObj) {
			let entry=dirObj[fileName];
			if(entry instanceof Object){
				return entry;
			}
			return null;
		}
		return null;
	};
	
	//-----------------------------------------------------------------------
	//Set item entry-info by path
	jaxDisk.setEntryInfo=async function(path,info){
		let self=this;
		let entry,pms;
		delete info.name;
		delete info.dir;
		delete info.disk;
		entry=await this.getEntry(path);
		if(typeof(entry)==="object"){
			let dir,fileName,writeVersion;
			[fileName,dir]=divPath(path);
			if(dir.startsWith("/")){
				dir=dir.substring(1);
			}
			if(!dir){
				dir='.';
			}
			Object.assign(entry,info);
			if(self.writeObj){
				await self.writeObj;
			}
			writeVersion=self.writeVsn++;
			self.writeObj=pms=get(dir,self.dbStore).then((dirInfo)=>{
				dirInfo[fileName]=entry;
				return set(dir,dirInfo,self.dbStore);
			});
			pms.writeVsn=writeVersion;
			return pms;
		}
	};
	
	//-----------------------------------------------------------------------
	//copy a file or dir, src can from another disk (orgDisk)
	jaxDisk.copyFile=function(path,newPath,overwrite=1,orgDisk=null){
		var self=this;
		var dirList,fileList;
		orgDisk=orgDisk||this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(path.endsWith("/")){
			path=path.substring(0,path.length-1);
		}
		if(!path){
			path='.';
		}
		
		if(newPath.startsWith("/")){
			newPath=newPath.substring(1);
		}
		if(newPath.endsWith("/")){
			newPath=newPath.substring(0,newPath.length-1);
		}
		if(!newPath){
			newPath='.';
		}
		
		dirList=[];
		fileList=[];
		
		async function checkInItem(itemPath,tgtPath) {
			var itemObj,subPath,subTgtPath,curItem;
			itemObj=await get(itemPath,orgDisk.dbStore);
			if(itemObj instanceof Uint8Array){
				curItem=await get(tgtPath,self.dbStore);//Is target there?
				if(curItem) {
					if(overwrite && curItem instanceof Uint8Array) {//Can't overwrite a dir with file!
						fileList.push({org: itemPath, tgt: tgtPath});
					}
				}else {
					fileList.push({org: itemPath, tgt: tgtPath});
				}
			}else if(typeof(itemObj)==="object"){
				var stub,itemName,name;
				dirList.push({org:itemPath,tgt:tgtPath});
				for(itemName in itemObj){
					name=itemName;
					stub=itemObj[name];
					subPath=itemPath?(itemPath+"/"+stub.name):stub.name;
					subTgtPath=tgtPath?(tgtPath+"/"+stub.name):stub.name;
					await checkInItem(subPath,subTgtPath);
				}
			}
		}
		
		function copyOneFile(stub){
			return orgDisk.loadFile(stub.org).then(fileData=>{
				return self.writeFile(stub.tgt,fileData);
			});
		}
		
		return get(path,orgDisk.dbStore).then(async fileObj=>{
			let i,n,pList;
			if(!fileObj){
				throw "Missing copy source: "+path;
			}
			await checkInItem(path,newPath);
			pList=[];
			n=dirList.length;
			for(i=0;i<n;i++){
				pList.push(self.newDir(dirList[i].tgt));
			}
			return Promise.allSettled(pList).then(async ()=>{
				let pList=[],p,stub;
				n=fileList.length;
				for(i=0;i<n;i++){
					stub=fileList[i];
					p=copyOneFile(stub);
					pList.push(p);
				}
				return Promise.allSettled(pList).then(()=>{
					return dirList.map((item)=>{
						return item.tgt;
					}).concat(fileList.map(item=>{
						return item.tgt;
					}));
				});
			});
		});
	};
	
	//-----------------------------------------------------------------------
	//Rename a file/dir
	jaxDisk.rename=function(path,newPath){
		var self=this;
		let orgName,orgPath,tgtName,tgtPath;
		
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(path.endsWith("/")){
			path=path.substring(0,path.length-1);
		}
		if(!path){
			path='.';
		}
		[orgName, orgPath] = divPath(path);
		
		if(newPath.startsWith("/")){
			newPath=newPath.substring(1);
		}
		if(newPath.endsWith("/")){
			newPath=newPath.substring(0,newPath.length-1);
		}
		if(!newPath){
			newPath='.';
		}
		[tgtName, tgtPath] = divPath(newPath);
		
		if(tgtPath!==orgPath){
			throw "Path error."
		}
		if(orgName===tgtName){//Same name:
			return (async function(){return true})();
		}
		
		return self.copyFile(path,newPath).then(()=>{
			return self.del(path);
		});
	};
	
	//-----------------------------------------------------------------------
	//Get all items path-name in a flat list:
	jaxDisk.getAllItemPath=async function(){
		return await keys(this.dbStore);
	};
	
	//-----------------------------------------------------------------------
	//Load a file's base version:
	jaxDisk.loadFileBase=async function(path,encode=null){
		let self,fileObj;
		self=this;
		if(path.startsWith("/")){
			path=path.substring(1);
		}
		if(!self.baseStore){
			return null;
		}
		fileObj=await get(path,self.baseStore);
		if(fileObj instanceof Uint8Array){
			if(encode) {
				let enc = new TextDecoder("utf-8");
				return enc.decode(fileObj);
			}else {
				return fileObj;
			}
		}
		return null;
	};
}

//****************************************************************************
//JAXDisk functions based on jaxDisk
//****************************************************************************
{
	//------------------------------------------------------------------------
	JAXDisk$1.cwd=function(){
		return JAXDisk$1.appPath;
	};
	
	//------------------------------------------------------------------------
	JAXDisk$1.chdir=JAXDisk$1.setPath=function(path){
		if(path[0]!=='/'){
			path=pathLib$1.join(JAXDisk$1.appPath,path);
			if(path[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		JAXDisk$1.appPath=path;
	};
	
	//-----------------------------------------------------------------------
	JAXDisk$1.parsePath=function (fullPath){
		let pos,diskName,diskPath;
		if(fullPath[0]!=='/'){
			fullPath=pathLib$1.join(JAXDisk$1.appPath,fullPath);
			if(fullPath[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		pos=fullPath.indexOf("/",1);
		if(pos<0){
			diskName=fullPath.substring(1);
			diskPath="";
		}else {
			diskName=fullPath.substring(1,pos);
			diskPath=fullPath.substring(pos+1);
		}
		return [diskName,diskPath];
	};

	//-----------------------------------------------------------------------
	//Get disk and path-on-disk:
	let parseDiskPath=JAXDisk$1.parseDiskPath=async function (fullPath){
		let pos,diskName,diskPath,disk;
		if(fullPath[0]!=='/'){
			fullPath=pathLib$1.join(JAXDisk$1.appPath,fullPath);
			if(fullPath[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		pos=fullPath.indexOf("/",1);
		if(pos<0){
			diskName=fullPath.substring(1);
			diskPath="";
		}else {
			diskName=fullPath.substring(1,pos);
			diskPath=fullPath.substring(pos+1);
		}
		disk=await JAXDisk$1.openDisk(diskName,false);
		return [disk,diskPath,diskName];
	};
	
	//-----------------------------------------------------------------------
	//Get disk and path-on-disk:
	let parseDiskPathSync=JAXDisk$1.parseDiskPath=function (fullPath){
		let pos,diskName,diskPath,disk;
		if(fullPath[0]!=='/'){
			fullPath=pathLib$1.join(JAXDisk$1.appPath,fullPath);
			if(fullPath[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		pos=fullPath.indexOf("/",1);
		if(pos<0){
			diskName=fullPath.substring(1);
			diskPath="";
		}else {
			diskName=fullPath.substring(1,pos);
			diskPath=fullPath.substring(pos+1);
		}
		disk=JAXDisk$1.diskHash[diskName];
		return [disk,diskPath,diskName];
	};
	
	//-----------------------------------------------------------------------
	JAXDisk$1.getPathDiskName=function(fullPath){
		let pos,diskName;
		if(fullPath[0]!=='/'){
			fullPath=pathLib$1.join(JAXDisk$1.appPath,fullPath);
			if(fullPath[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		pos=fullPath.indexOf("/",1);
		if(pos<0){
			diskName=fullPath.substring(1);
		}else {
			diskName=fullPath.substring(1,pos);
		}
		return diskName;
		
	};
	
	//-----------------------------------------------------------------------
	JAXDisk$1.getPathDisk=function(fullPath){
		let pos,diskName,disk;
		if(fullPath[0]!=='/'){
			fullPath=pathLib$1.join(JAXDisk$1.appPath,fullPath);
			if(fullPath[0]!=='/') {
				throw Error('Full path must starts with "/"');
			}
		}
		pos=fullPath.indexOf("/",1);
		if(pos<0){
			diskName=fullPath.substring(1);
		}else {
			diskName=fullPath.substring(1,pos);
		}
		disk=JAXDisk$1.diskHash[diskName];
		return disk;
	
	};
	
	//-----------------------------------------------------------------------
	//Make a new dir:
	JAXDisk$1.newDir=async function(fullPath,allowDisk=false,recursive=true){
		let [disk,diskPath,diskName]=await parseDiskPath(fullPath);
		if(typeof(allowDisk)==="object"){
			let options=allowDisk;
			allowDisk=options.allowDisk||false;
			recursive=options.recursive||false;
		}
		if(!disk){
			if(!allowDisk) {
				return false;
			}else {
				disk=await JAXDisk$1.newDisk(diskName);
				if(!diskPath){
					return true;
				}
			}
		}
		await disk.newDir(diskPath,false,recursive);
		return true;
	};
	
	JAXDisk$1.newDirSync=function(fullPath,recursive=true){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(typeof(recursive)==="object"){
			recursive=recursive.recursive||false;
		}
		if(!disk){
			return false;
		}
		disk.newDirSync(diskPath,recursive);
	};
	
	//-----------------------------------------------------------------------
	//Delete a entry:
	JAXDisk$1.del=async function(fullPath,allowDisk=false,recursive=true){
		let list;
		let [disk,diskPath,diskName]=await parseDiskPath(fullPath);
		if(typeof(allowDisk)==="object"){
			let options=allowDisk;
			allowDisk=options.allowDisk||false;
			recursive=options.recursive||false;
		}
		if(!disk){
			if(!allowDisk) {
				return false;
			}
		}
		list=await JAXDisk$1.getEntries(fullPath);
		if(list && list.length>0 && !recursive){
			return false;
		}
		if(!diskPath){
			if(!allowDisk){
				return false;
			}
			await JAXDisk$1.dropDisk(diskName);
			return true;
		}
		await disk.del(diskPath);
		return true;
	};
	
	JAXDisk$1.delSync=function(fullPath,recursive=true){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(typeof(recursive)==="object"){
			recursive=recursive.recursive||false;
		}
		if(!disk){
			return false;
		}
		disk.delSync(diskPath,recursive);
	};
	
	//-----------------------------------------------------------------------
	//Read a file with full path:
	JAXDisk$1.readFile=async function(path,encode){
		let data;
		let [disk,diskPath]=await parseDiskPath(path);
		data=await disk.readFile(diskPath,encode);
		if(data===null){
			throw Error(`${path}: can't read contents.`);
		}
		return data;
	};
	
	JAXDisk$1.readFileSync=function(fullPath,encode){
		let data;
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return false;
		}
		data=disk.readFileSync(diskPath,encode);
		if(data===null){
			throw Error(`${fullPath}: can't read contents.`);
		}
		return data;
	};
	
	//-----------------------------------------------------------------------
	//Write a file with full path:
	JAXDisk$1.writeFile=async function(path,data,encode){
		let [disk,diskPath]=await parseDiskPath(path);
		return await disk.writeFile(diskPath,data,encode);
	};
	
	JAXDisk$1.writeFileSync=function(fullPath,data,encode){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return false;
		}
		return disk.writeFileSync(diskPath,encode);
	};
	
	//-----------------------------------------------------------------------
	//Get a entry with full path:
	JAXDisk$1.getEntry=async function(path){
		if(path==="/") {
			return {name:"/",dir:1,root:1};
		}
		let [disk,diskPath]=await parseDiskPath(path);
		if(disk){
			return await disk.getEntry(diskPath);
		}else {
			return null;
		}
	};
	
	JAXDisk$1.getEntrySync=function(fullPath){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return null;
		}
		return disk.getEntrySync(diskPath);
	};
	
	//-----------------------------------------------------------------------
	//Set a entry info with full path:
	JAXDisk$1.setEntryInfo=async function(path,infoVO){
		let [disk,diskPath]=await parseDiskPath(path);
		return await disk.setEntryInfo(diskPath,infoVO);
	};
	
	JAXDisk$1.setEntryInfoSync=function(fullPath,infoVO){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return false;
		}
		return disk.setEntryInfoSync(diskPath,infoVO);
	};
	
	//-----------------------------------------------------------------------
	//Get entries under a full path:
	JAXDisk$1.getEntries=async function(path){
		if(path==="/"){
			let list= await JAXDisk$1.getDiskNames();
			list=list.map(name=>{return {name:name,dir:1,disk:1}});
			return list;
		}else {
			let [disk, diskPath] = await parseDiskPath(path);
			if(disk){
				return await disk.getEntries(diskPath);
			}else {
				return null;
			}
		}
	};
	
	JAXDisk$1.getEntriesSync=function(fullPath){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return null;
		}
		return disk.getEntriesSync(diskPath);
	};
	
	//-----------------------------------------------------------------------
	//Get entry names under a full path:
	JAXDisk$1.getEntryNames=async function(path){
		if(path==="/"){
			return await JAXDisk$1.getDiskNames();
		}
		let list=await JAXDisk$1.getEntries(path);
		if(!list){
			return null;
		}
		return list.map(item=>item.name);
	};
	JAXDisk$1.readDir=JAXDisk$1.getEntryNames;
	
	JAXDisk$1.getEntryNamesSync=function(fullPath){
		let list=JAXDisk$1.getEntriesSync(fullPath);
		if(!list){
			return null;
		}
		return list.map(item=>item.name);
	};
	JAXDisk$1.readDirSync=JAXDisk$1.getEntryNamesSync;
	
	//-----------------------------------------------------------------------
	//Check if a entry is there
	JAXDisk$1.isExist=async function(path){
		let entry=await JAXDisk$1.getEntry(path);
		return !!entry;
	};
	
	JAXDisk$1.isExistSync=function(fullPath){
		let [disk,diskPath,diskName]=parseDiskPathSync(fullPath);
		if(!disk){
			return false;
		}
		return disk.isExistSync(diskPath);
	};
	
	//-----------------------------------------------------------------------
	//Copy a file or a dir to a new path:
	JAXDisk$1.copy=async function(orgPath,tgtPath,options){
		let [orgDisk,orgDiskPath]=await parseDiskPath(orgPath);
		let [tgtDisk,tgtDiskPath]=await parseDiskPath(tgtPath);
		let overwrite=options?(options.force||false):false;
		await tgtDisk.copyFile(orgDiskPath,tgtDiskPath,overwrite,orgDisk);
	};
	
	JAXDisk$1.copySync=function(orgPath,tgtPath,options){
		let [orgDisk,orgDiskPath]=parseDiskPathSync(orgPath);
		let [tgtDisk,tgtDiskPath]=parseDiskPathSync(tgtPath);
		let overwrite=options?(options.force||false):false;
		tgtDisk.copySync(orgDiskPath,tgtDiskPath,overwrite,orgDisk);
	};
	
	//-----------------------------------------------------------------------
	//Move/ rename path:
	JAXDisk$1.move=async function(orgPath,tgtPath,options){
		let entry,overwrite;
		overwrite=options?options.force||false:false;
		if(orgPath.endsWith("/")){
			orgPath=orgPath.substring(orgPath.length-1);
		}
		if(tgtPath.endsWith("/")){
			tgtPath=tgtPath.substring(tgtPath.length-1);
		}
		entry=await JAXDisk$1.getEntry(orgPath);
		if(!entry){
			return false;
		}
		entry=await JAXDisk$1.getEntry(tgtPath);
		if(entry && !overwrite){
			return false;
		}
		if(orgPath===tgtPath || tgtPath.startsWith(orgPath+"/") || orgPath.startsWith(tgtPath+"/")){
			return false;
		}
		await JAXDisk$1.copy(orgPath,tgtPath,options);
		await JAXDisk$1.del(orgPath);
		return true;
	};

	JAXDisk$1.moveSync=function(orgPath,tgtPath,options){
		let entry,overwrite;
		overwrite=options?options.force||false:false;
		entry=JAXDisk$1.getEntrySync(orgPath);
		if(!entry){
			return false;
		}
		entry=JAXDisk$1.getEntrySync(tgtPath);
		if(entry && !overwrite){
			return false;
		}
		if(orgPath===tgtPath || tgtPath.startsWith(orgPath) || orgPath.startsWith(orgPath)){
			return false;
		}
		JAXDisk$1.copySync(orgPath,tgtPath,options);
		JAXDisk$1.delSync(orgPath);
		return true;
	};
	
	//--------------------------------------------------------------------------
	//Base version access:
	JAXDisk$1.loadFileBase=async function(path,encode=null){
		let [disk,diskPath]=await parseDiskPath(path);
		return disk.loadFileBase(diskPath,encode);
	};
}

//****************************************************************************
//JAXMemDisk
//****************************************************************************
{
	//-----------------------------------------------------------------------
	//Constructor:
	JAXMemDisk=function(disk){
		this.disk=disk;
		this.entries=new Map();
		this.name=disk.name;
		this.inMemory=true;
		disk.memDisk=this;
		this.actorId=null;
	};
	jaxMemDisk=JAXMemDisk.prototype={};
	
	//-----------------------------------------------------------------------
	//Init memery disk, read all entries into memory
	jaxMemDisk.init=async function(){
		let disk,keys,plist,entries;
		console.warn(`Sync-init disk: ${this.name}. Better use async access whenever possible.`);
		disk=this.disk;
		entries=this.entries;
		keys=await disk.getAllItemPath();
		plist=[];
		function readEntry(path){
			return get(path,disk.store).then(fileObj=>{
				entries.set(path,fileObj);
			});
		}
		for(let key of keys){
			plist.push(readEntry(key));
		}
		await Promise.all(plist);
		"/"+this.name+"/";
		this.actorId=await JAXDisk$1.watch("/"+this.name,(act,path,actorId)=>{
			if(actorId===this.actorId){
				return;
			}
			switch(act){
				case "NewDir":{
					this.newDirSync(path);
					break;
				}
				case "Del":{
					this.delSync(path);
					break;
				}
				case "File":{
					this.disk.readFile().then(data=>{
						this.writeFileSync(path,data);
					});
					break;
				}
			}
		});
		return true;
	};
	//***********************************************************************
	//Sync functions:
	//***********************************************************************
	{
		//-------------------------------------------------------------------
		//Create a new dir
		jaxMemDisk.newDirSync=function(path){
			let upDir,tgtName,upDirObj,time,curEntry;
			if(path.startsWith("/")){
				path=path.substring(1);
			}
			if(path.endsWith("/")){
				path=path.substring(0,path.length-1);
			}
			if(path==="."||path===""){
				throw Error(`Illegal dir name: ${path}`);
			}
			curEntry=this.entries.get(path);
			if(curEntry){
				if(curEntry.dir){
					return true;
				}
				throw Error(`/${this.name}/path is a file, can't create dir at same place.`);
			}
			[tgtName,upDir]=divPath(path);
			if(!upDir){
				upDir=this.entries.get(".");
			}else {
				upDirObj=this.entries.get(upDir);
			}
			if(!upDirObj){
				this.newDirSync(upDir);
				upDirObj=this.entries.get(upDir);
				if(!upDirObj){
					return false;
				}
			}
			time=Date.now();
			upDirObj[tgtName]={name:tgtName,createTime:time,dir:1};
			this.entries.set(path,{});
			this.disk.newDir(path,{actor:this.actorId});
			return true;
		};
		jaxDisk.newDirSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.newDirSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Delete a entry item:
		jaxMemDisk.delSync=function(path){
			let upDir,tgtName,curEntry,upDirObj;
			if(path.startsWith("/")){
				path=path.substring(1);
			}
			if(path.endsWith("/")){
				path=path.substring(0,path.length-1);
			}
			if(path==="."||path===""){
				throw Error(`Illegal dir name: ${path}`);
			}
			curEntry=this.entries.get(path);
			if(!curEntry){
				return true;
			}
			[tgtName,upDir]=divPath(path);
			if(!upDir){
				upDirObj=this.entries.get(".");
			}else {
				upDirObj=this.entries.get(upDir);
			}
			if(!upDirObj){
				throw Error(`Path: /${this.name}/${upDir} is not available.`);
			}
			if(curEntry.dir){
				let list=this.getEntriesSync(path);
				for(let subItem of list){
					this.delSync(path+"/"+subItem.name);
				}
			}
			delete upDirObj[tgtName];
			this.entries.delete(path);
			this.disk.del(path,{actor:this.actorId});
			return true;
		};
		jaxDisk.delSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.delSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Read a file content
		jaxMemDisk.readFileSync=function(path,encode){
			let data;
			data=this.entries.get(path);
			if(!(data instanceof Uint8Array)){
				return null;
			}
			if(encode){
				let enc = new TextDecoder("utf-8");
				return enc.decode(data);
			}
			return data;
		};
		jaxDisk.readFileSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.readFileSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Write a file
		jaxMemDisk.writeFileSync=function(path,data,encode){
			let byteAry,tgtName,upPath,time,upObj,fileStub,orgStub;
			if(encode) {
				data=""+data;//Lazy convert
			}
			if(path.startsWith("/")){
				path=path.substring(1);
			}
			if(path.endsWith("/")){
				throw Error(`${path} can't be a file name.`)
			}
			
			[tgtName,upPath]=divPath(path);
			time=Date.now();
			
			//Ensure saved object is ByteArray
			if (typeof (data) === 'string') {
				let encoder = new TextEncoder();
				byteAry = encoder.encode(data);
			} else if (data instanceof File) {
				throw Error("File object can't do sync write, convert to Uint8Array before write.");
			} else if (data instanceof Uint8Array) {
				byteAry = data;
			}else if(data instanceof ArrayBuffer){
				byteAry = new Uint8Array(data);
			}
			upObj=this.entries.get(upPath);
			if(upObj) {
				if(!upObj.dir){
					throw Error(`${upPath} is not a dir, can't write file under it.`)
				}
			}else {
				this.newDirSync(upPath);
				upObj=this.entries.get(upPath);
				if(!upObj){
					throw Error(`${upPath} can't be create.`)
				}
			}
			orgStub=upObj[tgtName];
			if(orgStub){
				if(orgStub.dir){
					throw Error(`/${this.name}/${path} is a dir, can't be overwrite by a file.`);
				}
				fileStub=orgStub;
			}else {
				fileStub = {
					name: tgtName,
					modified:true,
					createTime:time
				};
				upObj[tgtName]=fileStub;
			}
			fileStub.size=byteAry.length;
			fileStub.modifyTime=time;
			digestBytes(byteAry).then(hex=>{
				fileStub.hash=hex;
			});
			this.entries.set(path,byteAry);
			this.disk.writeFile(path,byteAry,encode);
		};
		jaxDisk.writeFileSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.writeFileSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Check entry exist:
		jaxMemDisk.isExistSync=function(path){
			if(path.endsWith("/")){
				path=path.substring(0,path.length-1);
			}
			if(path==="" || path==="."){
				return true;
			}
			return !!this.entries.get(path);
			
		};
		jaxDisk.isExistSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.isExistSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Get a file entry:
		jaxMemDisk.getEntrySync=function(path){
			let dir,fileName;
			[fileName,dir]=divPath(path);
			if(dir.startsWith("/")){
				dir=dir.substring(1);
			}
			if(dir.endsWith("/")){
				dir=dir.substring(0,dir.length-1);
			}
			if(!dir){
				dir='.';
				if(fileName===""){
					return {name:this.name,dir:1,disk:1};
				}
			}
			dir=this.entries.get(dir);
			if(dir) {
				let entry=dir[fileName];
				if(entry instanceof Object){
					return entry;
				}
				return null;
			}
			return null;
		};
		jaxDisk.getEntrySync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.getEntrySync(...args);
		};
		
		//-------------------------------------------------------------------
		//Get sub items' entry under a path
		jaxMemDisk.getEntriesSync=function(path){
			let dir;
			if(path.startsWith("/")){
				path=path.substring(1);
			}
			if(path.endsWith("/")){
				path=path.substring(0,path.length-1);
			}
			if(path===""){
				path=".";
			}
			dir=this.entries.get(path);
			if(dir){
				if(dir instanceof Uint8Array){
					return null;//This is a file, not dir
				}
				return Object.values(dir);
			}
			return null;
		};
		jaxDisk.getEntriesSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.getEntriesSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Set a entry info:
		jaxMemDisk.setEntryInfoSync=function(path,info){
			let dir,fileName;
			[fileName,dir]=divPath(path);
			if(dir.startsWith("/")){
				dir=dir.substring(1);
			}
			if(dir.endsWith("/")){
				dir=dir.substring(0,dir.length-1);
			}
			if(!dir){
				return;//Can't set disk root info
			}
			dir=this.entries.get(dir);
			if(dir && dir.dir) {
				let orgInfo=dir[fileName];
				if(!orgInfo){
					return false;
				}
				//These key is critical and not to be changed here:
				delete info.name;
				delete info.dir;
				delete info.disk;
				Object.assign(orgInfo,info);
				return true;
			}
			return false;
		};
		jaxDisk.setEntryInfoSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.setEntryInfoSync(...args);
		};
		
		//-------------------------------------------------------------------
		//Copy a file/dir:
		jaxMemDisk.copySync=function (orgPath,newPath,overwrite=1,orgDisk=null){
			let self=this;
			let orgEntry,tgtEntry;
			if(orgPath.endsWith("/")){
				orgPath=orgPath.substring(0,orgPath.length-1);
			}
			if(newPath.startsWith("/")){
				newPath=newPath.substring(1);
			}
			if(newPath.endsWith("/")){
				newPath=newPath.substring(0,orgPath.length-1);
			}
			if(orgPath.startsWith("/")){
				orgPath=orgPath.substring(1);
			}
			orgDisk=orgDisk||this;
			if(orgDisk.memDisk){
				orgDisk=orgDisk.memDisk;
			}
			if(!orgDisk.readFileSync){
				throw Error(`orgDisk ${orgDisk.name} can not sync access.`);
			}
			function copyOneFile(orgDisk,orgPath,tgtPath){
				let data;
				data=orgDisk.readFileSync(orgPath);
				self.writeFileSync(tgtPath,data);
			}
			orgEntry=orgDisk.getEntrySync(orgPath);
			tgtEntry=self.getEntrySync(newPath);
			if(orgEntry.dir){
				let list,subItem;
				if(tgtEntry && !tgtEntry.dir) {
					if(!overwrite) {
						return false;
					}
					self.delSync(newPath);
				}
				self.newDirSync(newPath);
				list=orgDisk.getEntriesSync(orgPath);
				for(subItem of list){
					if(subItem.dir){
						self.copySync(orgPath+"/"+subItem.name,newPath+"/"+subItem.name,overwrite,orgDisk);
					}else {
						let tgtPath=newPath+"/"+subItem.name;
						tgtEntry=self.getEntrySync(tgtPath);
						if(tgtEntry){
							if(tgtEntry.dir || !overwrite){
								continue;
							}
						}
						copyOneFile(orgDisk,orgPath+"/"+subItem.name,tgtPath);
					}
				}
				return true;
			}else {
				if(tgtEntry){
					if(!overwrite)
						return false;
					if(tgtEntry.dir) {
						throw Error(`/${self.name}/${newPath} is a dir, can't overwrite by file /${orgDisk.name}/${orgPath}`);
					}
				}
				
				copyOneFile(orgDisk,orgPath,newPath);
				return true;
			}
		};
		jaxDisk.copySync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.memDisk.copySync(...args);
		};
		
		//-------------------------------------------------------------------
		//Move a file/dir:
		jaxMemDisk.moveSync=function (orgPath,newPath,overwrite=1,orgDisk=null){
			this.copySync(orgPath,newPath,overwrite,orgDisk);
			orgDisk.delSync(orgPath);
		};
		jaxDisk.moveSync=function(...args){
			if(!this.memDisk){
				throw Error(`Disk ${this.name} is not in memory to async access.`);
			}
			return this.moveSync.copySync(...args);
		};
	}
}

//****************************************************************************
//Watch API:
//****************************************************************************
{
	//------------------------------------------------------------------------
	notifyModifyAct=function(act,path,actor){
		//let sw=navigator.serviceWorker.controller;
		let sw=JAXDisk$1.swControler;
		if (sw) {
			actor=actor||"";
			sw.postMessage({msg:"WatchAct",act:act,path:path,actor:actor});
		}
	};
}
var staticFS = JAXDisk$1;

//>>>>>>Node2Coke>>>>>>
var module$1$2={exports:{}};
var module$4=module$1$2;

var R$2 = typeof Reflect === 'object' ? Reflect : null;
var ReflectApply$1 = R$2 && typeof R$2.apply === 'function'
	? R$2.apply
	: function ReflectApply(target, receiver, args) {
		return Function.prototype.apply.call(target, receiver, args);
	};

var ReflectOwnKeys$1;
if (R$2 && typeof R$2.ownKeys === 'function') {
	ReflectOwnKeys$1 = R$2.ownKeys;
} else if (Object.getOwnPropertySymbols) {
	ReflectOwnKeys$1 = function ReflectOwnKeys(target) {
		return Object.getOwnPropertyNames(target)
			.concat(Object.getOwnPropertySymbols(target));
	};
} else {
	ReflectOwnKeys$1 = function ReflectOwnKeys(target) {
		return Object.getOwnPropertyNames(target);
	};
}

function ProcessEmitWarning$1(warning) {
	if (console && console.warn) console.warn(warning);
}

var NumberIsNaN$1 = Number.isNaN || function NumberIsNaN(value) {
	return value !== value;
};

function EventEmitter$1() {
	EventEmitter$1.init.call(this);
}
module$4.exports = EventEmitter$1;
module$4.exports.once = once$1;

// Backwards-compat with node 0.10.x
EventEmitter$1.EventEmitter = EventEmitter$1;

EventEmitter$1.prototype._events = undefined;
EventEmitter$1.prototype._eventsCount = 0;
EventEmitter$1.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners$1 = 10;

function checkListener$1(listener) {
	if (typeof listener !== 'function') {
		throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
	}
}

Object.defineProperty(EventEmitter$1, 'defaultMaxListeners', {
	enumerable: true,
	get: function() {
		return defaultMaxListeners$1;
	},
	set: function(arg) {
		if (typeof arg !== 'number' || arg < 0 || NumberIsNaN$1(arg)) {
			throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
		}
		defaultMaxListeners$1 = arg;
	}
});

EventEmitter$1.init = function() {
	
	if (this._events === undefined ||
		this._events === Object.getPrototypeOf(this)._events) {
		this._events = Object.create(null);
		this._eventsCount = 0;
	}
	
	this._maxListeners = this._maxListeners || undefined;
};

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter$1.prototype.setMaxListeners = function setMaxListeners(n) {
	if (typeof n !== 'number' || n < 0 || NumberIsNaN$1(n)) {
		throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
	}
	this._maxListeners = n;
	return this;
};

function _getMaxListeners$1(that) {
	if (that._maxListeners === undefined)
		return EventEmitter$1.defaultMaxListeners;
	return that._maxListeners;
}

EventEmitter$1.prototype.getMaxListeners = function getMaxListeners() {
	return _getMaxListeners$1(this);
};

EventEmitter$1.prototype.emit = function emit(type) {
	var args = [];
	for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
	var doError = (type === 'error');
	
	var events = this._events;
	if (events !== undefined)
		doError = (doError && events.error === undefined);
	else if (!doError)
		return false;
	
	// If there is no 'error' event listener then throw.
	if (doError) {
		var er;
		if (args.length > 0)
			er = args[0];
		if (er instanceof Error) {
			// Note: The comments on the `throw` lines are intentional, they show
			// up in Node's output if this results in an unhandled exception.
			throw er; // Unhandled 'error' event
		}
		// At least give some kind of context to the user
		var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
		err.context = er;
		throw err; // Unhandled 'error' event
	}
	
	var handler = events[type];
	
	if (handler === undefined)
		return false;
	
	if (typeof handler === 'function') {
		ReflectApply$1(handler, this, args);
	} else {
		var len = handler.length;
		var listeners = arrayClone$1(handler, len);
		for (var i = 0; i < len; ++i)
			ReflectApply$1(listeners[i], this, args);
	}
	
	return true;
};

function _addListener$1(target, type, listener, prepend) {
	var m;
	var events;
	var existing;
	
	checkListener$1(listener);
	
	events = target._events;
	if (events === undefined) {
		events = target._events = Object.create(null);
		target._eventsCount = 0;
	} else {
		// To avoid recursion in the case that type === "newListener"! Before
		// adding it to the listeners, first emit "newListener".
		if (events.newListener !== undefined) {
			target.emit('newListener', type,
				listener.listener ? listener.listener : listener);
			
			// Re-assign `events` because a newListener handler could have caused the
			// this._events to be assigned to a new object
			events = target._events;
		}
		existing = events[type];
	}
	
	if (existing === undefined) {
		// Optimize the case of one listener. Don't need the extra array object.
		existing = events[type] = listener;
		++target._eventsCount;
	} else {
		if (typeof existing === 'function') {
			// Adding the second element, need to change to array.
			existing = events[type] =
				prepend ? [listener, existing] : [existing, listener];
			// If we've already got an array, just append.
		} else if (prepend) {
			existing.unshift(listener);
		} else {
			existing.push(listener);
		}
		
		// Check for listener leak
		m = _getMaxListeners$1(target);
		if (m > 0 && existing.length > m && !existing.warned) {
			existing.warned = true;
			// No error code for this since it is a Warning
			// eslint-disable-next-line no-restricted-syntax
			var w = new Error('Possible EventEmitter memory leak detected. ' +
				existing.length + ' ' + String(type) + ' listeners ' +
				'added. Use emitter.setMaxListeners() to ' +
				'increase limit');
			w.name = 'MaxListenersExceededWarning';
			w.emitter = target;
			w.type = type;
			w.count = existing.length;
			ProcessEmitWarning$1(w);
		}
	}
	
	return target;
}

EventEmitter$1.prototype.addListener = function addListener(type, listener) {
	return _addListener$1(this, type, listener, false);
};

EventEmitter$1.prototype.on = EventEmitter$1.prototype.addListener;

EventEmitter$1.prototype.prependListener =
	function prependListener(type, listener) {
		return _addListener$1(this, type, listener, true);
	};

function onceWrapper$1() {
	if (!this.fired) {
		this.target.removeListener(this.type, this.wrapFn);
		this.fired = true;
		if (arguments.length === 0)
			return this.listener.call(this.target);
		return this.listener.apply(this.target, arguments);
	}
}

function _onceWrap$1(target, type, listener) {
	var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
	var wrapped = onceWrapper$1.bind(state);
	wrapped.listener = listener;
	state.wrapFn = wrapped;
	return wrapped;
}

EventEmitter$1.prototype.once = function once(type, listener) {
	checkListener$1(listener);
	this.on(type, _onceWrap$1(this, type, listener));
	return this;
};

EventEmitter$1.prototype.prependOnceListener =
	function prependOnceListener(type, listener) {
		checkListener$1(listener);
		this.prependListener(type, _onceWrap$1(this, type, listener));
		return this;
	};

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter$1.prototype.removeListener =
	function removeListener(type, listener) {
		var list, events, position, i, originalListener;
		
		checkListener$1(listener);
		
		events = this._events;
		if (events === undefined)
			return this;
		
		list = events[type];
		if (list === undefined)
			return this;
		
		if (list === listener || list.listener === listener) {
			if (--this._eventsCount === 0)
				this._events = Object.create(null);
			else {
				delete events[type];
				if (events.removeListener)
					this.emit('removeListener', type, list.listener || listener);
			}
		} else if (typeof list !== 'function') {
			position = -1;
			
			for (i = list.length - 1; i >= 0; i--) {
				if (list[i] === listener || list[i].listener === listener) {
					originalListener = list[i].listener;
					position = i;
					break;
				}
			}
			
			if (position < 0)
				return this;
			
			if (position === 0)
				list.shift();
			else {
				spliceOne$1(list, position);
			}
			
			if (list.length === 1)
				events[type] = list[0];
			
			if (events.removeListener !== undefined)
				this.emit('removeListener', type, originalListener || listener);
		}
		
		return this;
	};

EventEmitter$1.prototype.off = EventEmitter$1.prototype.removeListener;

EventEmitter$1.prototype.removeAllListeners =
	function removeAllListeners(type) {
		var listeners, events, i;
		
		events = this._events;
		if (events === undefined)
			return this;
		
		// not listening for removeListener, no need to emit
		if (events.removeListener === undefined) {
			if (arguments.length === 0) {
				this._events = Object.create(null);
				this._eventsCount = 0;
			} else if (events[type] !== undefined) {
				if (--this._eventsCount === 0)
					this._events = Object.create(null);
				else
					delete events[type];
			}
			return this;
		}
		
		// emit removeListener for all listeners on all events
		if (arguments.length === 0) {
			var keys = Object.keys(events);
			var key;
			for (i = 0; i < keys.length; ++i) {
				key = keys[i];
				if (key === 'removeListener') continue;
				this.removeAllListeners(key);
			}
			this.removeAllListeners('removeListener');
			this._events = Object.create(null);
			this._eventsCount = 0;
			return this;
		}
		
		listeners = events[type];
		
		if (typeof listeners === 'function') {
			this.removeListener(type, listeners);
		} else if (listeners !== undefined) {
			// LIFO order
			for (i = listeners.length - 1; i >= 0; i--) {
				this.removeListener(type, listeners[i]);
			}
		}
		
		return this;
	};

function _listeners$1(target, type, unwrap) {
	var events = target._events;
	
	if (events === undefined)
		return [];
	
	var evlistener = events[type];
	if (evlistener === undefined)
		return [];
	
	if (typeof evlistener === 'function')
		return unwrap ? [evlistener.listener || evlistener] : [evlistener];
	
	return unwrap ?
		unwrapListeners$1(evlistener) : arrayClone$1(evlistener, evlistener.length);
}

EventEmitter$1.prototype.listeners = function listeners(type) {
	return _listeners$1(this, type, true);
};

EventEmitter$1.prototype.rawListeners = function rawListeners(type) {
	return _listeners$1(this, type, false);
};

EventEmitter$1.listenerCount = function(emitter, type) {
	if (typeof emitter.listenerCount === 'function') {
		return emitter.listenerCount(type);
	} else {
		return listenerCount$1.call(emitter, type);
	}
};

EventEmitter$1.prototype.listenerCount = listenerCount$1;
function listenerCount$1(type) {
	var events = this._events;
	
	if (events !== undefined) {
		var evlistener = events[type];
		
		if (typeof evlistener === 'function') {
			return 1;
		} else if (evlistener !== undefined) {
			return evlistener.length;
		}
	}
	
	return 0;
}

EventEmitter$1.prototype.eventNames = function eventNames() {
	return this._eventsCount > 0 ? ReflectOwnKeys$1(this._events) : [];
};

function arrayClone$1(arr, n) {
	var copy = new Array(n);
	for (var i = 0; i < n; ++i)
		copy[i] = arr[i];
	return copy;
}

function spliceOne$1(list, index) {
	for (; index + 1 < list.length; index++)
		list[index] = list[index + 1];
	list.pop();
}

function unwrapListeners$1(arr) {
	var ret = new Array(arr.length);
	for (var i = 0; i < ret.length; ++i) {
		ret[i] = arr[i].listener || arr[i];
	}
	return ret;
}

function once$1(emitter, name) {
	return new Promise(function (resolve, reject) {
		function errorListener(err) {
			emitter.removeListener(name, resolver);
			reject(err);
		}
		
		function resolver() {
			if (typeof emitter.removeListener === 'function') {
				emitter.removeListener('error', errorListener);
			}
			resolve([].slice.call(arguments));
		}		
		eventTargetAgnosticAddListener$1(emitter, name, resolver, { once: true });
		if (name !== 'error') {
			addErrorHandlerIfEventEmitter$1(emitter, errorListener, { once: true });
		}
	});
}

function addErrorHandlerIfEventEmitter$1(emitter, handler, flags) {
	if (typeof emitter.on === 'function') {
		eventTargetAgnosticAddListener$1(emitter, 'error', handler, flags);
	}
}

function eventTargetAgnosticAddListener$1(emitter, name, listener, flags) {
	if (typeof emitter.on === 'function') {
		if (flags.once) {
			emitter.once(name, listener);
		} else {
			emitter.on(name, listener);
		}
	} else if (typeof emitter.addEventListener === 'function') {
		// EventTarget does not have `error` event semantics like Node
		// EventEmitters, we do not listen for `error` events here.
		emitter.addEventListener(name, function wrapListener(arg) {
			// IE does not have builtin `{ once: true }` support so we
			// have to do it manually.
			if (flags.once) {
				emitter.removeEventListener(name, wrapListener);
			}
			listener(arg);
		});
	} else {
		throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
	}
}

//**********************************************************************************************************************
//Make a object emitter
//**********************************************************************************************************************
var makeObjEventEmitter$1;
{
	let emitDeep=0;
	makeObjEventEmitter$1=function(obj){
		let events={};
		let mute=0;
		if(obj.emit){
			return;
		}
		obj.on=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			callback._call_once=false;
			if(!cbkSet){
				events[msg]=cbkSet=new Set();
				cbkSet.mute=0;
			}
			cbkSet.add(callback);
		};
		obj.once=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			callback._call_once=true;
			if(!cbkSet){
				events[msg]=cbkSet=new Set();
				cbkSet.mute=0;
			}
			cbkSet.add(callback);
		};
		obj.off=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			if(cbkSet){
				cbkSet.delete(callback);
			}
		};
		obj.muteEmit=function(msg){
			if(!msg) {
				mute += 1;
			}else {
				let cbkSet;
				cbkSet=events[msg];
				if(!cbkSet){
					events[msg]=cbkSet=new Set();
					cbkSet.mute=0;
				}
				cbkSet.mute+=1;
			}
		};
		obj.unmuteEmit=function(msg){
			if(!msg) {
				mute -= 1;
			}else {
				let cbkSet;
				cbkSet=events[msg];
				if(cbkSet){
					cbkSet.mute+=1;
				}
			}
		};
		obj.emit=function(msg,...args){
			let cbkSet,cbks,cbk;
			if(mute)
				return;
			cbkSet=events[msg];
			emitDeep++;
			if(emitDeep>20){
				console.warn("Emit too deep, no more emits");
				emitDeep--;
				return;
			}
			if(cbkSet){
				if(!cbkSet.mute) {
					cbks = Array.from(cbkSet.keys());
					for (cbk of cbks) {
						cbk(...args);
						if (cbk._call_once) {
							cbkSet.delete(cbk);
						}
					}
				}
			}
			emitDeep--;
		};
		obj.eventNames=function(){
			return Object.keys(events);
		};
		obj.removeAllListeners=function(eventName){
			if(eventName){
				let cbkSet;
				cbkSet=events[eventName];
				if(cbkSet){
					cbkSet.clear();
				}
			}else {
				events={};
			}
		};
	};
}

//***************************************************************************
//callAtfer function:
//***************************************************************************
let callAfter$2;
{
	let aboutCall=0;
	let callList=[];
	let makeCall=function(){
		let list,i,n;
		list=callList;
		aboutCall=0;
		callList=[];
		n=list.length;
		for(i=0;i<n;i++){
			list[i]();
		}
	};
	callAfter$2=async function(func,timeout){
		let pms;
		if(!timeout){
			callList.push(func);
			if(aboutCall){
				return;
			}
			aboutCall=1;
			pms=new Promise((resolve,reject)=>{
				resolve();
			});
			await pms;
			makeCall();
			return;
		}
		window.setTimeout(func,timeout);
	};
}

//***************************************************************************
//Notify-Object
//***************************************************************************
let makeNotify$2;
{
	makeNotify$2=function(self){
		let m_NotifyPaused;
		let m_viewHubIn = {};
		let m_viewHubOn = {};
		let m_isInEnvList = 0;
		let m_NotifyOnMsgHash = {};
		let m_PendingNofifyOn=[];
		let m_msgValHash={};
		let removeValBindOfView;
		let notifyToMap,notifyHubOn,notifyOnAll;
		let muteNotify=false;
		if(self.emitNotify){
			return;
		}
		//---------------------------------------------------------------
		//make a property val notify-able, fires notify when this property changes:
		self.upgradeVal = function (name, msg) {
			var oldMsg, curVal, desc, oldGet, oldSet,msgList;
			if (!(name in self)) {
				return;
			}
			if (!msg) {
				msg = "*";//default notify message is "*"
			}
			if(Array.isArray(msg)){
				msgList=msg;
			}
			oldMsg = m_msgValHash[name];
			if (oldMsg) {
				if (msg !== oldMsg) {
					throw "JAXDataObj upgradVal error: val " + name + " is already been upgraded with diffrent msg " + oldMsg + ", new msg: " + msg;
				}
				return;
			}
			desc = Object.getOwnPropertyDescriptor(self, name);
			oldGet = desc.get;
			oldSet = desc.set;
			curVal = self[name];
			m_msgValHash[name] = msg;
			if(msgList){
				//Mapping:
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							let msg;
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							for(msg of msgList) {
								//notifyHubIn(msg);//这个要去掉
								notifyHubOn(msg);
							}
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}else {
				//Mapping:
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							notifyHubOn(msg);
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}
		};
		
		//---------------------------------------------------------------
		//Get a "upgraded" property val's notify message string:
		self.getValMsg = function (name) {
			return m_msgValHash[name];
		};
		
		//---------------------------------------------------------------
		//Install a message tracer:
		self.onNotify=self.bindValNotify = function (msgName,func,view,once=0) {
			var map, set, msg;
			if (!func) {
				console.error("hub notify function!!");
				return;
			}
			if (!(msgName in self)) {
				msg=msgName;
			}else {
				msg = m_msgValHash[msgName];
			}
			if(!msg){
				throw ""+msgName+" is not upgraded!";
			}
			map = m_viewHubOn[msg];
			if (!map) {
				map = m_viewHubOn[msg] = new Map();
				map.mute=0;
			}
			set = map.get(view);
			if (!set) {
				set = new Set();
				map.set(view, set);
			}
			if(!once) {
				set.add(func);
			}else {
				let onceFunc;
				onceFunc=function(...args){
					func(...args);
					self.off(msg,onceFunc,view);
				};
				set.add(onceFunc);
			}
			return msg;
		};
		
		//---------------------------------------------------------------
		//Install an one-time message tracer
		self.onceNotify=function(msgName,func,view){
			self.onNotify(msgName,func,view,1);
		};
		
		//---------------------------------------------------------------
		//Uninstall all message tracers of a view
		self.removeValBindOfView = removeValBindOfView = function (msgName, view) {
			var list, i;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				list = m_viewHubOn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				return;
			}
			list = m_viewHubIn[msgName];
			if (list) {
				list.delete(view);
			}
			list = m_viewHubOn[msgName];
			if (list) {
				list.delete(view);
			}
		};
		
		//---------------------------------------------------------------
		//Uninstall a message tracer:
		self.offNotify=self.removeValNotify = function (msgName, func, view) {
			var list, map, set, i, msg;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					msg=i;
					self.removeValNotify(msg, view, func);
				}
				list = m_viewHubOn;
				for (i in list) {
					msg=i;
					self.removeValNotify(i, view, func);
				}
				return;
			}
			map = m_viewHubIn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
			map = m_viewHubOn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
		};
		
		//---------------------------------------------------------------
		notifyToMap = function (map) {
			var views, view, set, func;
			views = map.keys();
			for (view of views) {
				if (!view || view.allowValNotify!==false) {
					set = map.get(view);
					for (func of set) {
						func();
					}
				}
			}
		};
		
		//---------------------------------------------------------------
		//Set to fire a message notify, 
		self.emitNotify=self.notifyValMsgOn = notifyHubOn = function (msg) {
			if(!m_NotifyOnMsgHash[msg] && !muteNotify) {
				let map = m_viewHubOn[msg];
				if(map && map.mute){
					return;
				}
				
				m_NotifyOnMsgHash[msg] = 1;
				m_PendingNofifyOn.push(msg);
				if (m_isInEnvList)
					return;
				m_isInEnvList = 1;
				callAfter$2(notifyOnAll);
			}
		};
		
		//---------------------------------------------------------------
		//Fire all panding messages:
		notifyOnAll = function () {
			var map, msg, list, loop;
			m_isInEnvList = 0;
			if (m_NotifyPaused) {
				return;
			}
			loop = 0;
			do {
				list = m_PendingNofifyOn.splice(0);
				for (msg of list) {
					m_NotifyOnMsgHash[msg] = 0;
					map = m_viewHubOn[msg];
					if (map) {
						notifyToMap(map);
					}
				}
				loop++;
				if (loop > 3) {
					console.warn(`JAXDataObj notify too many times.`);
					break;
				}
			} while (m_PendingNofifyOn.length);
		};
		
		//---------------------------------------------------------------
		Object.defineProperty(self,"pauseValNotify",{
			get:function(){
				return m_NotifyPaused;
			},
			set:function(v){
				v=v?1:0;
				m_NotifyPaused=v;
				return v;
			}
		});
		
		//-------------------------------------------------------------------
		self.muteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (!map) {
					map = m_viewHubOn[msg] = new Map();
					map.mute=1;
				}
			}else {
				muteNotify++;
			}
		};
		
		//-------------------------------------------------------------------
		self.unmuteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (map) {
					map.mute-=1;
				}
			}else {
				muteNotify--;
			}
		};
	};
}
module$1$2.exports['once'];
//<<<<<<Node2Coke<<<<<<

var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Use a lookup table to find the index.
var lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
for (var i$1 = 0; i$1 < chars.length; i$1++) {
	lookup[chars.charCodeAt(i$1)] = i$1;
}
var encode = function (arraybuffer) {
	var bytes, i, len, base64;
	if(typeof(arraybuffer)==="string"){
		let encoder = new TextEncoder();
		arraybuffer = encoder.encode(arraybuffer);
	}
	if(arraybuffer instanceof Uint8Array){
		bytes=arraybuffer;
	}else {
		bytes= new Uint8Array(arraybuffer);
	}
	base64='';
	len=bytes.length;
	for (i = 0; i < len; i += 3) {
		base64 += chars[bytes[i] >> 2];
		base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
		base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
		base64 += chars[bytes[i + 2] & 63];
	}
	if (len % 3 === 2) {
		base64 = base64.substring(0, base64.length - 1) + '=';
	}
	else if (len % 3 === 1) {
		base64 = base64.substring(0, base64.length - 2) + '==';
	}
	return base64;
};

var decode = function (base64) {
	var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
	if (base64[base64.length - 1] === '=') {
		bufferLength--;
		if (base64[base64.length - 2] === '=') {
			bufferLength--;
		}
	}
	var arraybuffer = new ArrayBuffer(bufferLength);
	var bytes = new Uint8Array(arraybuffer);
	for (i = 0; i < len; i += 4) {
		encoded1 = lookup[base64.charCodeAt(i)];
		encoded2 = lookup[base64.charCodeAt(i + 1)];
		encoded3 = lookup[base64.charCodeAt(i + 2)];
		encoded4 = lookup[base64.charCodeAt(i + 3)];
		bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
		bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
		bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
	}
	return arraybuffer;
};

var decodeBytes = function (base64) {
	var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
	if (base64[base64.length - 1] === '=') {
		bufferLength--;
		if (base64[base64.length - 2] === '=') {
			bufferLength--;
		}
	}
	var arraybuffer = new ArrayBuffer(bufferLength);
	var bytes = new Uint8Array(arraybuffer);
	for (i = 0; i < len; i += 4) {
		encoded1 = lookup[base64.charCodeAt(i)];
		encoded2 = lookup[base64.charCodeAt(i + 1)];
		encoded3 = lookup[base64.charCodeAt(i + 2)];
		encoded4 = lookup[base64.charCodeAt(i + 3)];
		bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
		bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
		bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
	}
	return bytes;
};
var Base64 = {encode,decode,decodeBytes};

let basePath="/ws/";
let callSeq=0;

//----------------------------------------------------------------------------
//JAX用来进行WebAPI调用的类:
var WebAPI={
	path:null,
};

//----------------------------------------------------------------------------
//API调用:
WebAPI.makeCall=function(msg,vo,timeOut=0){
	var msgVO,text,self;
	this.path||basePath;
	self=this;
	msgVO={msg:msg,vo:vo,seq:callSeq++};
	text=JSON.stringify(msgVO);
	if(timeOut>0){
		return new Promise((okFunc,errFunc)=>{
			let canceled=0;
			window.setTimeout(()=>{
				canceled=1;
				errFunc({code:503,info:"Web API call time out."});
			},timeOut);
			fetch(self.path||basePath,{
				method: 'POST',
				cache: 'no-cache',
				headers: {
					'Content-Type': 'application/json'
				},
				body:text
			}).then(res=>{
				if(!canceled){
					okFunc(res.json());
				}
			}).catch(err=>{
				if(!canceled){
					errFunc(err);
				}
			});
		});
	}
	return fetch(self.path||basePath,{
		method: 'POST',
		cache: 'no-cache',
		headers: {
			'Content-Type': 'application/json'
		},
		body:text
	}).then(res=>{
		return res.json().then(resVO=>{
			if(!("code" in resVO)){
				resVO.code=res.status;
			}
			return resVO;
		});
	});
};

//----------------------------------------------------------------------------
//设置APIPath:
WebAPI.setAPIPath=function(path){
	this.path=path;
};

//----------------------------------------------------------------------------
//得到API的Path
WebAPI.getPath=async function(){
	let vo;
	if(this.path){
		return this.path;
	}
	vo=await this.makeCall("apiPath",{});
	if(vo.code===200){
		this.path=vo.path;
		return this.path;
	}
	return null;
};

//----------------------------------------------------------------------------
WebAPI.fetch=async function(url,options){
	let msgVO,callVO,text,body;
	callVO={
		url:url,
		...options
	};
	msgVO={
		msg:"WebFetch",vo:callVO,seq:callSeq++
	};
	body=callVO.body;
	if(body){
		if(body instanceof Uint8Array){
			body=Base64.encode(body);
		}else if(typeof(body)==="string"){
			body=Base64.encode(body);
		}else if(body instanceof ArrayBuffer){
			body=Base64.encode(body);
		}else if(typeof(body)==="object"){
			body=JSON.stringify(body);
			body=Base64.encode(body);
		}
		callVO.body=body;
	}
	text=JSON.stringify(msgVO);
	return fetch(self.path||basePath,{
		method: 'POST',
		cache: 'no-cache',
		headers: {
			'Content-Type': 'application/json'
		},
		body:text
	})
};
WebAPI.fetch;

//CokeCodes could API helper:
let CokeNT=function(){
	makeNotify$2(this);
	this.loginVO=null;				//Cloud-Login-VO
	this.loginDone=0;				//Is login done and ok
	this.loginPreview=false;		//Is logined as a preview user?
	this.previewVO=null;			//Preview login-info
	this.checkLoginTimer=null;		//Timer to check login
};
let cokeNT=CokeNT.prototype={};


//----------------------------------------------------------------------------
//Genterate a string's SHA code.
let digestMessage=cokeNT.digestMessage=async function(message) {
	const msgUint8 = new TextEncoder().encode(message);                           // encode as (utf-8) Uint8Array
	const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);           // hash the message
	const hashArray = Array.from(new Uint8Array(hashBuffer));                     // convert buffer to byte array
	const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
	return hashHex;
};

//----------------------------------------------------------------------------
//User login callVO={email:string,passwordSHA:string}
cokeNT.login=async function(callVO){
	let vo,self,savedVO;
	let time;

	time=Date.now();
	self=this;
	if(callVO){
		let sha=callVO.passwordSHA;
		if(sha){
			callVO.time=time;
			callVO.passwordSHA=await digestMessage(""+time+sha);
		}
	}else {
		savedVO=this.loadLoginInfo();
		if(!savedVO || !savedVO.userId){
			throw "No saved login info.";
		}
		callVO={
			"userId":savedVO.userId,
			"time":Date.now(),
		};
		if(savedVO.token){
			if(time>savedVO.tokenExpire){
				//token expired:
				this.loginVO=null;
				this.loginDone=0;
				localStorage.removeItem("LoginVO");
				throw "Login token is expired.";
			}
			callVO.token=savedVO.token;
		}else {
			//没有token
			this.loginVO=null;
			this.loginDone=0;
			localStorage.removeItem("LoginVO");
			throw "Login token is invalid.";
		}
	}
	vo=await WebAPI.makeCall("apiPath",{});
	if(vo && vo.path){
		WebAPI.setAPIPath(vo.path);
		vo=await WebAPI.makeCall("userLogin",callVO);
		if(vo.code===200){
			vo.apiPath=WebAPI.path;
			self.saveLoginInfo(vo);	
			this.loginDone=1;
			this.loginVO=vo;
			this.userId=vo.userid;
			this.emitNotify("Online");
			return true;
		}else {
			this.loginVO=null;
			this.loginDone=0;
			localStorage.removeItem("LoginVO");
			throw new Error(`Login error ${vo.code}: ${vo.info}`);
		}
	}
	throw new Error("Login error: can't get API-Path.");
};

//----------------------------------------------------------------------------
//Log out cokecodes:
cokeNT.logout=async function(){
	if(this.loginDone){
		localStorage.setItem("LastAccount",this.loginVO.email);
	}
	this.loginVO=null;
	this.loginDone=0;
	localStorage.removeItem("LoginVO");
	this.emitNotify("Offline");
	return true;
};

//----------------------------------------------------------------------------
cokeNT.getLastAccount=function(){
	return localStorage.getItem("LastAccount");
};

//----------------------------------------------------------------------------
//Check if logined://
cokeNT.checkLogin=async function(readInfo=false,checkNT=false){
	let loginVO,time;
	if(this.checkLoginTimer){
		clearTimeout(this.checkLoginTimer);
		this.checkLoginTimer=null;
	}
	if(this.loginDone && this.loginVO &&!readInfo){
		return true;
	}
	time=Date.now();
	loginVO=this.loadLoginInfo();
	if(!loginVO){
		this.loginVO=null;
		if(this.loginDone){
			this.loginDone=0;
			this.emitNotify("Offline");
		}
		localStorage.removeItem("LoginVO");
		return false;
	}
	if(!loginVO.apiPath || !loginVO.userId || !loginVO.token || loginVO.tokenExipre<=time){
		this.loginVO=null;
		if(this.loginDone){
			this.loginDone=0;
			this.emitNotify("Offline");
		}
		localStorage.removeItem("LoginVO");
		return false;
	}
	this.loginVO=loginVO;
	if(checkNT){
		let res;
		try{
			res=await this.makeCall("userCurrency",{});
			if(!res || res.code!==200){
				throw "Offline";
			}
		}catch(err){
			this.loginDone=0;
			this.emitNotify("Offline");
			localStorage.removeItem("LoginVO");
			return false;
		}
	}
	if(!this.loginDone){
		this.loginDone=1;
		this.emitNotify("Online");
	}
	return true;
};

//----------------------------------------------------------------------------
cokeNT.maybePreview=async function(){
	let voText,vo;
	let res;
	if(this.loginDone && this.loginVO){
		return true;
	}
	voText=localStorage.getItem("PreviewLogin");
	if(!voText){
		this.loginPreview=false;
		return false;
	}
	try{
		vo=JSON.parse(voText);
	}catch(err){
		this.loginPreview=false;
		return false;
	}
	try{
		res=await this.makeCall("previewLogin",vo);
		if(!res || res.code!==200){
			this.loginPreview=false;
			return false;
		}
	}catch(err){
		this.loginPreview=false;
		return false;
	}
	this.loginPreview=true;
	this.previewVO=vo;
	return true;
};

//----------------------------------------------------------------------------
//Save login info:
cokeNT.saveLoginInfo=function(vo){
	let voText;
	this.loginVO=vo;
	voText=JSON.stringify(vo);
	localStorage.setItem("LoginVO",voText);
};

//----------------------------------------------------------------------------
//Read login info
cokeNT.loadLoginInfo=function(){
	let voText,vo;
	voText=localStorage.getItem("LoginVO");
	if(voText){
		vo=JSON.parse(voText);
		this.loginVO=vo;
		return vo;
	}
	return null;
};

//----------------------------------------------------------------------------
//Register a new user: regVO={email:string,passwordSHA:string,name:string}
cokeNT.register=async function(regVO){
	var self,vo;
	self=this;
	vo=await WebAPI.makeCall("userReg",regVO);
	if(vo.code===200){
		vo.apiPath=await WebAPI.getPath();
		self.saveLoginInfo(vo);	
		self.loginDone=1;
		self.loginVO=vo;
		self.userId=vo.userid;
		self.emitNotify("Online");
		return true;
	}else {
		throw "Register error "+vo.code+": "+vo.info;
	}
};

//----------------------------------------------------------------------------
//Make a call, if logined, append userId and token
cokeNT.makeCall=async function(msg,vo,timeout=0){
	if(this.loginDone){
		vo.userId=this.loginVO.userId;
		vo.token=this.loginVO.token;
	}else {
		let pvVO=this.previewVO;
		if(pvVO){
			vo.pvUserId=pvVO.userId;
			vo.pvSlot=pvVO.slot;
			vo.pvKey=pvVO.key;
		}
	}
	try{
		return await WebAPI.makeCall(msg,vo,timeout);
	}catch(e){
		if(e.code===503);
		throw e;
	}
};

let theCokeNT=new CokeNT(null);

let tabFS,tabTask,theSW,swControler;
let tabOS={
	shareFS:true,//If used shared FS by parent
	rootOS:null,//Root page's tabOS
	homePath:"/",
	fs:null,
	sw:null,
	swClient:null,
	task:null,
	heartBeat:true,
	allowRoot:false
};

async function createFS(){
	return staticFS;
}
//****************************************************************************
//Service worker client:
//****************************************************************************
let setupSWClient;
let swClient={
	uuid:crypto.randomUUID?crypto.randomUUID():(""+Date.now()+Math.floor(Math.random()*1000))
};
{
	let heartBeating=false;
	let heartTimer=null;
	let listenCnt=0;
	let handleMessage;
	//------------------------------------------------------------------------
	function _heartBeat(){
		if(!heartBeating){
			clearInterval(heartTimer);
			return;
		}
		fetch("/heart-beat").then(res=>{
			if(!res.ok){
				console.log("SW-heat-beat failed");
			}
		});
	}
	
	//------------------------------------------------------------------------
	swClient.startHeartBeat=function(){
		if(heartBeating)
			return;
		heartBeating=1;
		heartTimer=setInterval(_heartBeat,5000);
	};

	//------------------------------------------------------------------------
	swClient.stopHeartBeat=function(){
		heartBeating=0;
	};
	
	//------------------------------------------------------------------------
	swClient.startListen=function(heartBeat){
		if(!theSW){
			return;
		}
		if(!listenCnt){
			listenCnt=1;
			theSW.addEventListener("message",handleMessage);
			if(heartBeat && swControler){//Only root/page tabos need heart-beat
				this.startHeartBeat();
			}
		}else {
			listenCnt++;
		}
	};

	//------------------------------------------------------------------------
	swClient.stopListenSW=function(){
		if(!theSW){
			return;
		}
		if(listenCnt>0) {
			listenCnt--;
			if(!listenCnt){
				theSW.removeEventListener("message",handleMessage);
			}
		}
	};
	
	//------------------------------------------------------------------------
	swClient.postMessage=function(msg,vo){
		swControler && swControler.postMessage({...vo,msg:msg});
	};
	
	//------------------------------------------------------------------------
	handleMessage=function(event){
		let data=event.data;
		let msg=data.msg;
		swClient && swClient.emit(msg,data);
	};
	
	//------------------------------------------------------------------------
	setupSWClient=async function(heartBeat){
		if(!swClient)
			return;
		makeObjEventEmitter$1(swClient);
		tabOS.swClient=swClient;
		swClient && swClient.startListen(heartBeat);
	};
}

//****************************************************************************
//Route API:
//****************************************************************************
{
	let routeRegs={};

	//------------------------------------------------------------------------
	function routeStart(data){
		let path=data.path;
		let stub=routeRegs[path];
		stub.routeId=data.routeId;
		if(stub && stub.resolveCallback){
			stub.resolveCallback(stub);
		}
	}
	//------------------------------------------------------------------------
	async function routeCall(data){
		let path=data.path;
		let stub=routeRegs[path];
		data.callId;
		if(!swControler)
			return;
		if(!stub){
			swControler.postMessage({msg:"RouteRes",callId:data.callId,res:{code:404,body:"Route not found."}});
		}else {
			let req,request,ret,method,initVO;
			req=data.request;
			method=req.method||"GET";
			initVO={
				method:method,
				referrer:req.referrer,
				headers:req.headers||{}
			};
			if(method==="POST"){
				initVO.body=req.body;
			}
			request=new Request(req.url,initVO);
			try {
				ret = stub.callback(request);
				if(ret instanceof Promise){
					ret.then(async res=>{
						if(res instanceof Response){
							let body;
							if(res.bodyUsed){
								body=await readStream(res.body);
							}else {
								body=null;
							}
							res={
								body:body,
								code:res.status,
								headers:Object.assign({},res.headers),
							};
							swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: res });
						}else {
							swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: res });
						}
					}).catch((err)=>{
						swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: {code:500,body:""+err} });
					});
				}else {
					let res=ret;
					if(res instanceof Response){
						let body;
						if(res.bodyUsed){
							body=await readStream(res.body);
						}else {
							body=null;
						}
						res={
							body:body,
							code:res.status,
							headers:Object.assign({},res.headers),
						};
						swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: res });
					}else {
						swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: res });
					}
				}
			}catch(err){
				swControler.postMessage({ msg: "RouteRes", callId: data.callId, res: {code:500,body:""+err} });
			}
		}
	}

	//------------------------------------------------------------------------
	tabOS.regRoute=async function(path,callback){
		if(!swControler){
			return;
		}
		if(!tabOS.swClient){
			throw new Error("service worker client not ready: "+path);
		}
		{
			swClient.on("RouteStart",routeStart);
			swClient.on("RouteCall",routeCall);
		}
		return new Promise((resolve,reject)=>{
			if(routeRegs[path]){
				throw Error(`Route path ${path} already taken!`);
			}
			routeRegs[path]={
				path: path,
				callback: callback,
				resolveCallback: resolve,
				routeId: 0
			};
			swControler.postMessage({msg:"RouteOn",path:path});
		});
	};
		
	//-----------------------------------------------------------------------
	tabOS.stopRoute=function(path,callback){
		let stub;
		if(!swControler){
			return;
		}
		stub=routeRegs[path];
		if(stub){
			if(callback && callback!==stub.callback){
				return;
			}
			swControler.postMessage({msg:"RouteOff",path:path});
			delete stub[path];
		}
	};
}

//****************************************************************************
//Watch API:
//****************************************************************************
{
	let watching=false;
	let watchCallReady=false;
	let watchList=[];
	let watchClientId=null;
	let watchStubId=0;
	let watchResolveCallback=null;
	let watchResolveStubId=0;

	//-----------------------------------------------------------------------
	//Watch a path for changes:
	tabOS.watch=async function(path,callback){
		let stub;
		if(!swClient){
			throw new Error("Watch without swClient, path: "+path);
		}
		stub={
			path:path,
			callback:callback,
			id:(++watchStubId)
		};
		watchList.push(stub);
		return new Promise((resolve,reject)=>{
			if(!watching){
				watching=true;
				//Reigster watch handlers:
				if(!watchCallReady){
					watchCallReady=true;
					swClient.on("WatchOK",(data)=>{
						watchClientId=data.watchId;
						watchResolveCallback && watchResolveCallback(""+watchClientId+"-"+watchResolveStubId);
					});
					swClient.on("WatchAct",(data)=>{
						let act=data.act;
						let path=data.path;
						let actor=data.actor;
						let stub;
						for(let i=0,n=watchList.length;i<n;i++){
							stub=watchList[i];
							if(path.startsWith(stub.path)) {
								stub.callback(act, path, actor);
							}
						}
					});
				}
				//Send watch to Service-Worker
				watchResolveCallback=resolve;
				watchResolveStubId=stub.id;
				swControler.postMessage({msg:"Watch"});
			}else {
				resolve(""+watchClientId+"-"+stub.id);
			}
		});
	};
	
	//-----------------------------------------------------------------------
	//Unwatch:
	tabOS.unwatch=function(path,callback){
		let stub;
		for(let i=0,n=watchList.length;i<n;i++){
			stub=watchList[i];
			if(stub.path===path && stub.callback===callback){
				watchList.splice(i,1);
				i--;n--;
			}
		}
		if(!watchList.length){
			swControler.postMessage({msg:"Unwatch",watchId:watchClientId});
			watching=false;
		}
	};
}

//****************************************************************************
//OS features and API:
//****************************************************************************
{
	let setupPms=null,setupRootOS,setupFrameOS,setupPageOS;
	
	//------------------------------------------------------------------------
	setupRootOS=async function(){
		tabOS.rootOS=tabOS;//This is the root OS
		setupSWClient(tabOS.heartBeat);//Start SWClient with heart beat
		tabFS=await createFS();
		tabOS.fs=tabFS;
		await tabFS.init(swClient);
		
		tabOS.osTag=""+Date.now()+"-"+Math.trunc(Math.random()*1000);
		
		//init task:
		tabTask.initTask();
		tabOS.task=tabTask;

		//Fin:
		tabFS=tabOS.fs;
		tabFS.swClient=tabOS.swClient;
		tabFS.swControler=swControler;
		tabFS.regRoute=tabOS.regRoute;
		tabFS.stopRoute=tabOS.stopRoute;
		tabFS.watch=tabOS.watch.bind(tabOS);
		tabFS.unwatch=tabOS.unwatch.bind(tabOS);
		window.tabOS=tabOS;
	};
	
	//------------------------------------------------------------------------
	setupPageOS=async function(){
		let parentOS=window.parentTabOS;
		if(!parentOS){
			let rootWin;
			//wait parentTabOS;
			//alert("Refresh tabos app window or open tabos app manually will break the task management chain.");
			//rootWin=window.open("","TabOSHome");
			rootWin=window.opener;
			if(rootWin && rootWin.openTabOSAppPage){
				//Post a message to root win to open this app
				console.log("Will call root-win to open app");
				rootWin.openTabOSAppPage(document.location.href,window.name);
			}else {
				await setupRootOS();
				return;
			}
			window.close();
			throw "Wait home";
		}
		setupSWClient(true);//Start SWClient with heart beat
		tabOS.rootOS=parentOS.rootOS;
		tabOS.fs=await createFS();//Always create own FS
		tabOS.osTag=tabOS.rootOS.osTag;

		//init task:
		tabTask.initTask();
		tabOS.task=tabTask;

		//Fin:
		tabFS=tabOS.fs;
		tabFS.swClient=tabOS.swClient;
		tabFS.swControler=swControler;
		tabFS.regRoute=tabOS.regRoute;
		tabFS.stopRoute=tabOS.stopRoute;
		tabFS.watch=tabOS.watch.bind(tabOS);
		tabFS.unwatch=tabOS.unwatch.bind(tabOS);
		window.tabOS=tabOS;
	};
	
	//------------------------------------------------------------------------
	setupFrameOS=async function(){
		let win,parentOS;
		win=window;
		do{
			win=win.parent;
			parentOS=win.tabOS;
			if(win.parent===win){
				break;
			}
		}while(!parentOS && win);
		if(!parentOS){
			return await setupRootOS();
		}
		setupSWClient(false);//Start SWClient without heart beat
		tabOS.rootOS=parentOS.rootOS;
		tabOS.homePath=tabOS.rootOS.homePath||"/";
		tabOS.heartBeat=false;
		if(tabOS.shareFS){
			tabOS.fs=parentOS.fs;
		}else {
			tabOS.fs=await createFS();
		}
		tabOS.osTag=tabOS.rootOS.osTag;

		//init task:
		//tabTask.initTask();
		//tabOS.task=tabTask;
		tabOS.task=tabOS.rootOS.task;
		//Fin:
		tabFS=tabOS.fs;
		if(!tabOS.shareFS){
			tabFS.swClient=tabOS.swClient;
			tabFS.swControler=swControler;
			tabFS.regRoute=tabOS.regRoute;
			tabFS.stopRoute=tabOS.stopRoute;
			tabFS.watch=tabOS.watch.bind(tabOS);
			tabFS.unwatch=tabOS.unwatch.bind(tabOS);
		}
		window.tabOS=tabOS;
	};

	//------------------------------------------------------------------------
	tabOS.setup=async function(isRoot){
		if(setupPms){
			return setupPms;//Already
		}
		//Check service worker:
		theSW=navigator.serviceWorker||null;
		if(theSW){
			swControler=theSW.controller;
		}else {
			if(!window.webkit){
				throw Error("Missing TabOS service worker.");
			}
		}
		if(window.parent===window) {
			//This is a full-browser-tab page, check if this is the root page
			if((!isRoot) && document.referrer.startsWith(document.location.origin)){
				setupPms=setupPageOS();
				return await setupPms;
			}
			//We are the root:
			if(tabOS.allowRoot){
				window.openTabOSAppPage=function(url,name){
					setTimeout(()=>{
						let appWin=window.open(url,name);
						appWin.parentTabOS=window.tabOS;
					},100);
				};
				setupPms=setupRootOS();
				return await setupPms;
			}else {
				window.openTabOSAppPage=function(url,name){
					setTimeout(()=>{
						let appWin=window.open(url,name);
						appWin.parentTabOS=window.tabOS;
					},100);
				};
				setupPms=setupRootOS();
				return await setupPms;
			}
		}
		setupPms=setupFrameOS();
		return await setupPms;
	};
}

//****************************************************************************
//Task register, active and query:
//****************************************************************************
{
	let localTaskStub;
	let taskActive;
	let taskReqId=0;
	let taskReqs={};
	tabTask={};
	tabTask.initTask=function(){
		let winName,icon;
		winName = window.name;
		if(!swControler){
			return;
		}
		if (!winName) {
			let time;
			time = Date.now();
			winName = "TabOSWindow" + time + Math.trunc(1000 * Math.random());
			window.name = winName;
		}
		icon = document.head.querySelector("link[rel*='icon']");
		icon = icon ? icon.href : "";
		localTaskStub = {
			osTag:tabOS.osTag,
			windowName: winName,
			icon: icon,
			title: document.title,
		};
		taskActive();
		let el=document.getElementsByTagName("title")[0];
		if(el){
			let pl=el.parentElement;
			pl.addEventListener("DOMSubtreeModified",(evt)=>{
				let t = evt.target;
				if (t === el || (t.parentNode && t.parentNode === el)) {
					localTaskStub.title=document.title;
					taskActive();
				}
			});
		}

		//Send active message when page-window focused:
		window.addEventListener("focus", () => {
			localTaskStub.windowName=window.name;
			taskActive();
		});

		//Listen serviceWorkerClient's "Tasks" message:
		swClient.on("Tasks",(data)=>{
			let tasks=data.tasks;
			let req,reqId;
			reqId=data.reqId;
			req=taskReqs[reqId];
			if(req){
				req(tasks);
				delete taskReqs[reqId];
			}
		});
	};

	//------------------------------------------------------------------------
	tabTask.taskActive=taskActive=function(){
		swClient.postMessage("TaskActive",{msg:"TaskActive",stub:localTaskStub});
	};
	
	//-----------------------------------------------------------------------
	//Get all active tasks:
	tabTask.getTasks=async function(){
		if(!swControler){
			return [];
		}
		return new Promise((resolve,reject)=>{
			let reqId=""+(taskReqId++);
			let timer=setTimeout(()=>{
				resolve(null);
				delete taskReqs[reqId];
			},500);
			taskReqs[reqId]=(tasks)=>{
				let osTag=tabOS.osTag;
				clearTimeout(timer);
				tasks=tasks.filter(task=>{return task.osTag===osTag});
				resolve(tasks);
			};
			swClient.postMessage("GetTasks",{msg:"GetTasks", reqId:reqId});
		});
	};
}

const pptProxyIdx=0;
const pptWebObjIdx=1;
const pptStyleObjIdx=2;
const pptInitedIdx=3;
const pptPVTMapIdx=4;
const pptRefCountIdx=5;
const pptViewScopeIdx=6;
const pptChildrenIdx=7;
const pptDisplayIdx=8;
const pptDisplayCodeIdx=9;


let VFACT,VFACTObj;
let darkMode$1=false;
let lanCode=null;
VFACT={
	get version(){
		return "0.0.1";
	},
	get darkMode(){
		return darkMode$1;
	},
	set darkMode(mode){
		darkMode$1=mode;
	},
	get lanCode(){
		return lanCode;
	},
	set lanCode(code){
		lanCode=code;
	},
	classRegs:{
	},
	"sharedPath":"/~/-tabos/shared",
	"sharedAssets":"/~/-tabos/shared/assets",
};
//****************************************************************************
//shared util functions:
//****************************************************************************
let callAfter$1;
{
	//------------------------------------------------------------------------
	callAfter$1=async function(func,timeout,valMap){
		let pms;
		if(!timeout){
			pms=new Promise((resolve,reject)=>{
				resolve();
			});
			await pms;
			if(valMap){
				if(valMap[pptRefCountIdx]>0){
					func();
				}
			}else {
				func();
			}
			return;
		}
		if(valMap){
			if(valMap.$_pptMap){
				valMap=valMap.$_pptMap;
			}
			window.setTimeout(()=>{
				if(valMap[pptRefCountIdx]>0){
					func();
				}
			},timeout);
		}else {
			window.setTimeout(func,timeout);
		}
	};
}


//****************************************************************************
//nameHost feature:
//****************************************************************************
let nameHostList=[];
let curNameHost=null;
let pushNameHost,popNameHost,checkInNameObj;
{
	pushNameHost=VFACT.pushNameHost=function(obj) {
		nameHostList.push(obj);
		curNameHost = obj;
	};
	popNameHost=VFACT.popNameHost=function(obj) {
		if (obj && curNameHost !== obj) {
			console.error("nameHostList error!");
			return;
		}
		nameHostList.pop();
		curNameHost = nameHostList[nameHostList.length - 1];
	};
	checkInNameObj=VFACT.checkInNameObj=function (obj, actId, id) {
		let idx, hostObj;
		idx = nameHostList.length - 1;
		hostObj = nameHostList[idx];
		while (hostObj) {
			if (actId) {
				hostObj["#" + actId] = obj;
			}
			if (id) {
				hostObj[id] = obj;
			}
			if (hostObj.nameHostStop !== false) {
				return;
			}
			idx--;
			hostObj = nameHostList[idx];
		}
	};
}

//****************************************************************************
//Gear container feature:
//****************************************************************************
let containerHashes=[];
let gearSlotsList=[];
let curContainerHash=null;
let curGearSlots=null;
let pushContainerHash,popContainerHash;
{
	pushContainerHash=VFACT.pushContainerHash=function(obj,slots) {
		containerHashes.push(obj);
		gearSlotsList.push(slots);
		curContainerHash = obj;
		curGearSlots=slots;
	};
	popContainerHash=VFACT.popContainerHash=function(obj) {
		if (obj && curContainerHash !== obj) {
			console.error("containerHashes error!");
			return;
		}
		containerHashes.pop();
		gearSlotsList.pop();
		curContainerHash = containerHashes[containerHashes.length - 1];
		curGearSlots = gearSlotsList[containerHashes.length - 1];
	};
}

//****************************************************************************
//define PVT:
//****************************************************************************
let $PVT;
{
	$PVT=function(funcGet,traceObj){
		let val,funcSet,traced,traceView,traceFunc;
		traced=0;
		traceView=null;
		if(traceObj) {
			val = funcGet();
		}
		Object.defineProperty(this,"val",{
			get:function(){
				return traced?val:funcGet();
			}
		});
		this.traceObj=traceObj;
		
		traceFunc=function(){
			funcSet(funcGet());
		};
		
		//-------------------------------------------------------------------
		//apply trace:
		this.trace=function(func,viewScope,msg){
			traceView=viewScope;
			funcSet=func;
			val = funcGet();
			if(traceObj){
				if(traceObj.onChange) {
					traceObj.onChange(traceFunc);
					traced = 1;
				}else if(traceObj.onNotify){
					traceObj.onNotify(msg||"*",traceFunc,traceView);
					traced = 2;
				}
			}
		};
		
		//-------------------------------------------------------------------
		//stop trace
		this.untrace=function(){
			if(!traced || !funcSet){
				return;
			}
			if(traced===1){
				traceObj.offChange(traceFunc);
			}else if(traced===2){
				traceObj.offNotify("*",traceFunc,traceView);
			}
			traced=0;
		};
	};
}

let TypeDef;
let typeDefs = {};
//****************************************************************************
//TypeDef:
//****************************************************************************
{
	TypeDef = function (name, initStyle, initClass) {
		let defPpts, pptHash;
		this.name = name;
		pptHash = this.pptHash = {
			"proxy": 0,
			"webObj": 1,
			"styleObj": 2,
			"inited": 3,
			"pvtMap": 4,
			"refCount": 5,
			"viewScope": 6,
			"children": 7,
			"display": 8,
			"displayCode": 9,
		};
		let nextPptIdx = 10;
		defPpts = this.defaultPpts = [null, null, null, false, null, 1, null, null, true, ""];//null for pvt-map, view-scope and children; 1 for refCount
		this.allocPptIdx = function (pptName, defaultPpt) {
			let idx = nextPptIdx++;
			defPpts[idx] = defaultPpt;
			if (pptName) {
				pptHash[pptName] = idx;
			}
			return idx;
		};
		this.getPptIdx = function (pptName) {
			let idx;
			idx = pptHash[pptName];
			return idx === undefined ? -1 : idx;
		};
		this.setMap = new Map();
		this.getMap = new Map();
		this.initStyle = {
			boxSizing: "border-box",
			flex: "0 0 auto"
		};
		if (initStyle) {
			this.initStyle = { ...this.initStyle, ...initStyle };
		}
		this.initClass = initClass || null;
		typeDefs[name] = this;
		this.preCreateCodes = [];
		this.postCreateCodes = [];
	};
	let _typeDef = TypeDef.prototype = {};
	TypeDef.aliasType = function (orgName, newName) {
		typeDefs[newName] = typeDefs[orgName];
	};
	_typeDef.defineIdxOnlyPpt = function (name, initVal, hasPVT = false) {
		let idx = this.allocPptIdx(name, initVal);
		if (hasPVT) {
			this.definePpt(name,
				(valMap) => {return valMap[idx];},
				(valMap, val) => {valMap[idx] = val;},
				hasPVT);
		} else {
			this.getMap.set(name, idx);
			this.setMap.set(name, idx);
		}
		return idx;
	};
	_typeDef.defineIdxOnlyPptCall = function (name, initVal, hasPVT = false) {
		let idx = this.allocPptIdx(name, initVal);
		this.definePpt(name,
			(valMap) => {return valMap[idx];},
			(valMap, val) => {
				let pxy = valMap[pptProxyIdx];
				if (val instanceof Function) {
					val = val.bind(pxy);
				}
				valMap[idx] = val;
			},
			hasPVT);
		return idx;
	};
	_typeDef.defineFunction = function (name, func) {
		let funcIdx;
		funcIdx = this.getPptIdx(name + "()");
		if (funcIdx<0) {
			funcIdx = this.allocPptIdx(name + "()", null);
		}
		this.getMap.set(name, (valMap) => {
			let call_;
			if(!valMap){
				return func;
			}
			call_ = valMap[funcIdx];
			if (!call_) {
				call_ = valMap[funcIdx] = func.bind(valMap);
			}
			return call_;
		});
	};

	//--------------------------------------------------------------------------
	//Reg a prpoerty
	_typeDef.definePpt=function(name,getPpt,setPpt,hasPVT){
		let def,getMap,setMap;
		def=this;
		getMap=def.getMap;
		setMap=def.setMap;
		//Get:
		if(getPpt){
			getMap.set(name,getPpt);
		}
		//Set:
		if(!(setPpt instanceof Function)){
			return;
		}
		if(hasPVT){
			let pvtSlot;
			pvtSlot=def.allocPptIdx(null,null);
			setMap.set(name, (valMap,val) => {
				let oldPVT = valMap[pvtSlot];
				let pvtMap=valMap[pptPVTMapIdx];
				if (oldPVT) {
					oldPVT.untrace();
					valMap[pvtSlot] = null;
					pvtMap.delete(name);
				}
				if (val && val.trace) {
					if (val.traceObj) {
						val.trace((v)=>{setPpt(valMap,v);}, name, valMap[pptViewScopeIdx]);
						valMap[pvtSlot] = val;
						pvtMap.set(name,val);
					}
					val = val.val;
				}
				return setPpt(valMap,val);
			});
		}else {
			setMap.set(name,setPpt);
		}
	};
	_typeDef.aliasPpt=function(orgName,newName){
		let def,getMap,setMap;
		def=this;
		getMap=def.getMap;
		setMap=def.setMap;
		getMap.set(newName,getMap.get(orgName));
		setMap.set(newName,setMap.get(orgName));
	};
	_typeDef.hasPpt=function(name){
		let def,getMap,setMap;
		def=this;
		getMap=def.getMap;
		setMap=def.setMap;
		return !!(getMap.get(name)||setMap.get(name));
	};
}

//****************************************************************************
//VFACTObj
//****************************************************************************
{
	VFACTObj=function(type,webObj,styleObj,pptMap){
		this.$_type=type;
		this.$_webObj=webObj;
		this.$_styleObj=styleObj;
		this.$_pptMap=pptMap;
	};
	
	VFACT.createObj=function(def,owner=null,before=null){
		let type,typeDef,self,webObj,styleObj,pxy;
		let defChian=[];
		let defDisplay;//display property in def
		let isNameHost,slotDefs,gearSlots;
		if(!def){
			return null;
		}
		//Flatten def:
		if(typeof(def)==="string"){
			type=def;
			def={};
		}else {
			defChian.push(def);
			type=def.type||"div";
			while(typeof(type)==="object"){
				defChian.push(type);
				def={...type,...def,type:type.type};
				type=def.type||"div";
			}
		}

		//Check if we really create this element?
		if(("attached" in def)&&(!def.attached)){
			return null;
		}
		
		typeDef=typeDefs[type];
		if(!typeDef){
			console.log(`Can't find component type: ${type}`);
			return null;
		}
		type=typeDef;
		let hookMap,oldSetMap;
		let funcSetMap=type.setMap;
		let funcGetMap=type.getMap;
		let pptList=[...type.defaultPpts];
		pptList[pptPVTMapIdx]=new Map();//the PVT map
		//TODO: Support HTML-element direct creates:
		if(type.createElement){
			webObj=type.createElement(def,pptList);
		}else {
			webObj=document.createElement("div");
		}
		styleObj=webObj.style;
		pptList[pptWebObjIdx]=webObj;
		pptList[pptStyleObjIdx]=styleObj;
		if(type.initClass){
			webObj.className=type.initClass;
		}
		if(type.initStyle){
			Object.assign(styleObj,type.initStyle);
		}
		self=new VFACTObj(type,webObj,styleObj,pptList);
		self.$_hookSetAttr=function(attrName,func){
			let oldFunc;
			if(!hookMap){
				hookMap={};
				oldSetMap=funcSetMap;
				funcSetMap={
					get:function(name){
						let func;
						func=hookMap[name];
						if(func){
							return func;
						}
						return oldSetMap.get(name);
					}
				};
			}
			oldFunc=oldSetMap.get(attrName);
			if(oldFunc){
				hookMap[attrName]=function(...args){
					if(func.call(self,...args)===false){
						return;
					}
					oldFunc.call(self,...args);
				};
			}
		};
		
		pxy= new Proxy(self,{
			get(obj,pName){
				let func=funcGetMap.get(pName);
				if(func) {
					if(func>=0){
						return pptList[func];
					}
					return func(pptList);
				}
				return self[pName];
			},
			set(obj,pName,val){
				let func=funcSetMap.get(pName);
				if(func){
					if(func>=0) {
						pptList[func]=val;
						return true;
					}
					func(pptList,val);
					return true;
				}
				if(pName[0]!=="$" || pName[1]!=="_"){
					self[pName]=val;
				}
				return true;
			}
		});
		pptList[pptProxyIdx]=pxy;
		self.self=self;
		self.proxy=pxy;
		webObj.$_pxy=pxy;
		webObj.$_vfact=self;
		
		if(darkMode$1){
			styleObj.colorScheme="dark";
		}

		if("display" in def) {
			defDisplay = def.display || "";
		}else {
			defDisplay = 1;
		}
		def.display=0;
		styleObj.display="none";
		
		if(owner){
			if(owner instanceof VFACTObj){
				if(before){
					owner.insertBefore(pxy,before);
				}else {
					owner.appendChild(pxy);
				}
				pxy.release();
			}else {
				//should be HTML element:
				owner.appendChild(webObj);
			}
		}

		if(type.prefix){
			def=type.prefix(pxy,def,webObj,styleObj,pptList);
		}
		
		//apply def's properties:
		let defPpts,pptName;
		defPpts=Object.getOwnPropertyNames(def);
		for(pptName of defPpts){
			if(pptName.startsWith("$")){
				let preDef,desc;
				for(preDef of defChian){
					desc = Object.getOwnPropertyDescriptor(preDef, pptName);
					if(desc && (!("value" in desc))){
						let hasKey,val;
						pptName = pptName.substring(2);
						hasKey = pptName in def;
						if(hasKey){
							val = def[pptName];
						}else {
							hasKey = pptName in self;
							val = self[pptName];
						}
						Object.defineProperty(self, pptName, desc);
						if (hasKey) {
							self[pptName] = val;
						}
						break;
					}
				}
			}else {
				//Assign the ppt:
				pxy[pptName]=def[pptName];
			}
		}

		slotDefs=def.subContainers;
		if(slotDefs){
			gearSlots=pxy.subContainers={};
			slotDefs.nameProxy=curNameHost;
			pushContainerHash(slotDefs,gearSlots);
		}
		if(def.hash || def.id){
			checkInNameObj(pxy,def.hash,def.id);
		}
		isNameHost=def.faces||def.nameHost;
		if(isNameHost){
			pushNameHost(pxy);
			checkInNameObj(pxy,null,"#self");//confirm this:
		}
		let chdList=def.children;
		let gearNamePxy=null;
		if(curContainerHash){
			let gearChds,hash;
			hash=def.hash;
			gearChds=curContainerHash[hash];
			if(gearChds /*&& gearChds.length*/){
				curGearSlots[hash]=pxy;
				chdList=gearChds;
				gearNamePxy=curContainerHash.nameProxy;
				if(gearNamePxy){
					pushNameHost(gearNamePxy);
				}
			}
		}
		if(chdList && pxy.appendChild){
			let chdDef;
			for(chdDef of chdList){
				VFACT.createObj(chdDef,pxy);
			}
		}
		if(gearNamePxy){
			popNameHost(gearNamePxy);
		}
		if(defDisplay) {
			pxy.display=defDisplay;
		}
		pxy.doLayout && pxy.doLayout();
		if(type.postCreate){
			type.postCreate(pxy,def,webObj,styleObj,pptList);
		}
		if(isNameHost){
			popNameHost(pxy);
		}
		if(slotDefs){
			popContainerHash(slotDefs);
			slotDefs.nameProxy=null;
		}
		pptList[pptInitedIdx]=true;
		//all set, call OnCreate function:
		if(def.face){
			pxy.showFace(def.face);
		}
		if(pxy.OnCreate){
			pxy.OnCreate();
		}
		return pxy;
	};
	VFACT.pushNameHost=pushNameHost;
	VFACT.popNameHost=popNameHost;
	VFACT.checkInNameObj=checkInNameObj;
	
	VFACT.createFragDummy=function(owner){
		let frg=new DocumentFragment();
		frg.$_pxy=owner;
		return frg;
	};
	VFACT.appendFragDummy=function(frg,webObj,before){
		let pxy;
		if(!webObj){
			pxy=frg.$_pxy;
			webObj=pxy.webObj;
		}
		if(before){
			webObj.insertBefore(frg,before);
		}else {
			webObj.appendChild(frg);
		}
	};
}
{
	VFACTObj.vmcAddRefcount=function(){
		let valMap=this;
		valMap[pptRefCountIdx]+=1;
	};
	
	VFACTObj.vmcRelease=function(){
		let valMap=this;
		valMap[pptRefCountIdx]-=1;
		if(valMap[pptRefCountIdx]<=0){
			let pvtMap,pvt,self;
			let pxy=valMap[pptProxyIdx];
			let onFree,typeOnFree,pvts;
			self=pxy.self;
			onFree=pxy.OnFree;
			if(onFree){
				onFree.call(pxy);
			}
			typeOnFree=self.$_type.OnFree;
			if(typeOnFree){
				typeOnFree(valMap);
			}
			pxy.clearChildren();
			pvtMap=valMap[pptPVTMapIdx];
			if(pvtMap){
				pvts=pvtMap.values();
				for(pvt of pvts){
					pvt.untrace();
				}
				pvtMap.clear();
			}
			self.$_webObj=null;
			self.$_styleObj=null;
			valMap.splice(0);
		}
	};
	
	VFACTObj.objHas=function(objPxy,valName){
		
	};
}

VFACT.saveConfig=function(urlFix){
	urlFix=urlFix||window.location.pathname;
	localStorage.setItem(urlFix+">>darkMode",darkMode$1);
	if(lanCode!==null){
		localStorage.setItem(urlFix+">>lanCode",lanCode);
	}
};

VFACT.loadConfig=function(urlFix){
	urlFix=urlFix||window.location.pathname;
	darkMode$1=localStorage.getItem(urlFix+">>darkMode");
	darkMode$1=darkMode$1===null?null:(darkMode$1==="true");
	lanCode=localStorage.getItem(urlFix+">>lanCode");
};

VFACT.loadConfig();

//****************************************************************************
//UI templates:
//****************************************************************************
{
	let uiTemplates={};
	let uiEditTemplates={};
	VFACT.regUITemplate=function(name,template){
		uiTemplates[name]=template;
	};
	VFACT.getUITemplate=function(name){
		let def;
		def=uiTemplates[name];
		if(def instanceof Function){
			return def();
		}
		return def;
	};
	VFACT.getUITemplates=function(){
		return uiTemplates;
	};

	VFACT.regEditUITemplate=function(name,template){
		uiEditTemplates[name]=template;
	};
	VFACT.getEditUITemplate=function(name){
		let def;
		def=uiEditTemplates[name];
		if(def instanceof Function){
			return def();
		}
		return def;
	};
	VFACT.getEditUITemplates=function(){
		return uiEditTemplates;
	};
	
	VFACT.newUITemplateObj=function(template){
		let obj,ppts,pptName,pptTmp,pptType;
		if(typeof(template)==="string"){
			template=uiEditTemplates[template]||uiTemplates[template];
		}
		if(!template){
			return null;
		}
		ppts=template.properties;
		if(!ppts){
			return {};
		}
		obj={};
		for(pptName in ppts){
			pptTmp=ppts[pptName];
			pptType=pptTmp.type;
			switch(pptType){
				default:
					obj[pptName]=pptTmp.defaultValue;
					break;
				case "object":
					obj[pptName]=VFACT.newUITemplateObj(pptTmp);
					break;
				case "array":{
					let ary,elmtTmpt,initLen,initVal;
					ary=obj[pptName]=[];
					elmtTmpt=pptTmp.element;
					initLen=pptTmp.initLength;
					if(initLen>0){
						let i,elmtType,elmtClass;
						if(elmtTmpt){
							elmtType=elmtTmpt.type;
							for(i=0;i<initLen;i++){
								switch(elmtType){
									case "auto":
									case "string":
									default:
										initVal=elmtTmpt.defaultValue||"";
										ary.push(initVal);
										break;
									case "int":
									case "number":
										initVal=elmtTmpt.defaultValue||0;
										ary.push(initVal);
										break;
									case "bool":
										initVal=elmtTmpt.defaultValue||true;
										ary.push(initVal);
										break;
									case "object":
										elmtClass=elmtTmpt.class;
										if(elmtClass){
											ary.push(VFACT.newUITemplateObj(elmtClass));
										}else {
											ary.push({});
										}
										break;
									case "array":
										ary.push([]);
										break;
								}
							}
														
						}else {
							for(i=0;i<initLen;i++){
								ary.push("");	
							}
						}
					}
					break;
				}
			}
		}
		return obj;
	};
	
	VFACT.genTemplateByVal=function(pptVal,pptName){
		let pptType;
		pptType=typeof(pptVal);
		switch(pptType){
			case "undefined":
			default:
				pptType="auto";
				return {name:pptName,type:pptType};
			case "string":
				pptType="string";
				return {name:pptName,type:pptType};
			case "boolean":
				pptType="bool";
				return {name:pptName,type:pptType};
			case "number":
				pptType="number";
				return {name:pptName,type:pptType};
			case "object":
				if(pptVal===null){
					pptType="auto";
					return {name:pptName,type:pptType};
				}else if(Array.isArray(pptVal)){
					pptType="array";
					return {name:pptName,type:pptType};
				}else {
					pptType="object";
					return {name:pptName,type:pptType,class:null};
				}
		}
		return null;
	};
	
	VFACT.genTemplateByObject=function(obj,name=""){
		let pptName,pptVal,pptTmpt;
		let ppts={};
		let tmpt={
			name:name,type:"object",
			properties:ppts
		};
		for(pptName in obj){
			pptVal=obj[pptName];
			pptTmpt=VFACT.genTemplateByVal(pptVal,pptName);
			if(pptTmpt){
				ppts[pptName]=pptTmpt;
			}
		}
		return tmpt;
	};
}

//****************************************************************************
//DataLine:
//****************************************************************************
{
	let uiDataViewLines={};
	VFACT.regDataViewLine=function(name,def){
		uiDataViewLines[name]=def;
	};
	
	VFACT.getDataViewLine=function(name){
		return uiDataViewLines[name];
	};
	
	VFACT.getDataViewLines=function(){
		return uiDataViewLines;
	};
}

let makeNotify$1;
{
	makeNotify$1=function(self){
		var m_NotifyPaused;
		var m_viewHubIn = {};
		var m_viewHubOn = {};
		var m_isInEnvList = 0;
		var m_NotifyOnMsgHash = {};
		var m_PendingNofifyOn=[];
		var m_msgValHash={};
		var removeValBindOfView;
		var notifyToMap,notifyHubOn,notifyOnAll;
		var muteNotify=false;
		if(self.emitNotify){
			return;
		}
		//---------------------------------------------------------------
		//make changing [name] attrib notify [msg] message, if [msg] is uset, null or "", msg will be "*":
		self.upgradeVal = function (name, msg) {
			var oldMsg, curVal, desc, oldGet, oldSet,msgList;
			if (!(name in self)) {
				return;
			}
			if (!msg) {
				msg = "*";//Default message:
			}
			if(Array.isArray(msg)){
				msgList=msg;
			}
			oldMsg = m_msgValHash[name];
			if (oldMsg) {
				if (msg !== oldMsg) {
					throw "Notify upgradVal error: val " + name + " is already been upgraded with diffrent msg " + oldMsg + ", new msg: " + msg;
				}
				return;
			}
			desc = Object.getOwnPropertyDescriptor(self, name);
			oldGet = desc.get;
			oldSet = desc.set;
			curVal = self[name];
			m_msgValHash[name] = msg;
			if(msgList){
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							let msg;
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							for(msg of msgList) {
								notifyHubOn(msg);
							}
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}else {
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							notifyHubOn(msg);
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}
		};
		
		//---------------------------------------------------------------
		self.getValMsg = function (name) {
			return m_msgValHash[name];
		};
		
		//---------------------------------------------------------------
		self.onNotify=self.bindValNotify = function (msgName,func,view,once=0) {
			var map, set, msg;
			if (!func) {
				console.error("hub notify function!!");
				return;
			}
			if (!(msgName in self)) {
				msg=msgName;
			}else {
				msg = m_msgValHash[msgName];
			}
			if(!msg){
				throw ""+msgName+" is not upgraded!";
			}
			map = m_viewHubOn[msg];
			if (!map) {
				map = m_viewHubOn[msg] = new Map();
				map.mute=0;
			}
			set = map.get(view);
			if (!set) {
				set = new Set();
				map.set(view, set);
			}
			if(!once) {
				set.add(func);
			}else {
				let onceFunc;
				onceFunc=function(...args){
					func(...args);
					self.off(msg,onceFunc,view);
				};
				set.add(onceFunc);
			}
			return msg;
		};
		
		//---------------------------------------------------------------
		self.onceNotify=function(msgName,func,view){
			self.onNotify(msgName,func,view,1);
		};
		
		//---------------------------------------------------------------
		self.removeValBindOfView = removeValBindOfView = function (msgName, view) {
			var list, i;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				list = m_viewHubOn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				return;
			}
			list = m_viewHubIn[msgName];
			if (list) {
				list.delete(view);
			}
			list = m_viewHubOn[msgName];
			if (list) {
				list.delete(view);
			}
		};
		
		//---------------------------------------------------------------
		self.offNotify=self.removeValNotify = function (msgName, func, view) {
			var list, map, set, i, msg;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					msg=i;
					self.removeValNotify(msg, view, func);
				}
				list = m_viewHubOn;
				for (i in list) {
					msg=i;
					self.removeValNotify(i, view, func);
				}
				return;
			}
			map = m_viewHubIn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
			map = m_viewHubOn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
		};
		
		//---------------------------------------------------------------
		notifyToMap = function (map) {
			var views, view, set, func;
			views = map.keys();
			for (view of views) {
				if (!view || view.allowValNotify!==false) {
					set = map.get(view);
					for (func of set) {
						func();
					}
				}
			}
		};
		
		//---------------------------------------------------------------
		//Fire a notify message
		self.emitNotify=self.notifyValMsgOn = notifyHubOn = function (msg) {
			if(!m_NotifyOnMsgHash[msg] && !muteNotify) {
				let map = m_viewHubOn[msg];
				if(map && map.mute){
					return;
				}
				
				m_NotifyOnMsgHash[msg] = 1;
				m_PendingNofifyOn.push(msg);
				if (m_isInEnvList)
					return;
				m_isInEnvList = 1;
				callAfter$1(notifyOnAll);
			}
		};
		
		//---------------------------------------------------------------
		notifyOnAll = function () {
			var map, msg, list, loop;
			m_isInEnvList = 0;
			if (m_NotifyPaused) {
				return;
			}
			loop = 0;
			do {
				list = m_PendingNofifyOn.splice(0);
				for (msg of list) {
					m_NotifyOnMsgHash[msg] = 0;
					map = m_viewHubOn[msg];
					if (map) {
						notifyToMap(map);
					}
				}
				loop++;
				if (loop > 3) {
					console.warn(`Notify too many times.`);
					break;
				}
			} while (m_PendingNofifyOn.length);
		};
		
		//---------------------------------------------------------------
		Object.defineProperty(self,"pauseValNotify",{
			get:function(){
				return m_NotifyPaused;
			},
			set:function(v){
				v=v?1:0;
				m_NotifyPaused=v;
				return v;
			}
		});
		
		//-------------------------------------------------------------------
		self.muteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (!map) {
					map = m_viewHubOn[msg] = new Map();
					map.mute=1;
				}
			}else {
				muteNotify++;
			}
		};
		
		//-------------------------------------------------------------------
		self.unmuteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (map) {
					map.mute-=1;
				}
			}else {
				muteNotify--;
			}
		};
	};
	VFACT.makeNotify=makeNotify$1;
}

let VFACTState=function(orgObj){
	this.orgObj=orgObj;
};

//with strictState object, you can't set state's variable, you must call setState method to update state contents and trigger updates
let strictState=function(orgObj,viewScope,...subs){
	let curObj,proxy;
	let onChangeSet;//setState,,onChange,offChange,refresh;
	let willRefresh=0;
	function refresh(sub){
		let func;
		willRefresh=0;
		for(func of onChangeSet){
			func();
		}
		if(sub && subs){
			for(sub of subs){
				sub.refresh();
			}
		}
	}
	function setState(newObj){
		if(newObj instanceof Function){
			newObj=newObj(curObj);
		}
		curObj={
			...newObj,setState,onChange,offChange,refresh
		};
		if(!willRefresh){
			willRefresh=1;
			callAfter$1(refresh);
		}
	}
	function onChange(callback){
		onChangeSet.add(callback);
	}
	function offChange(callback){
		onChangeSet.delete(callback);
	}
	onChangeSet=new Set();
	curObj={
		...orgObj,
		setState,onChange,offChange,refresh
	};
	proxy=new Proxy(new VFACTState(orgObj),{
		get:function(obj,pName){
			return curObj[pName];
		},
		set:function(obj,pName,val){
			switch(pName){
				case "$owner":
					return true;
			}
			return false;
		}
	});
	return proxy;
};
VFACT.strictState=strictState;

//with flexState object, you can set state's variable and it will trigger updates
let flexState=function(orgObj,viewScope,...subs){
	let curObj,proxy;
	let onChangeSet;//setState,,onChange,offChange,refresh;
	let willRefresh=0;
	let pMap=new Map();
	function refresh(sub){
		let func;
		willRefresh=0;
		for(func of onChangeSet){
			func();
		}
		if(sub && subs){
			for(sub of subs){
				sub.refresh();
			}
		}
	}
	function setState(newObj){
		if(newObj instanceof Function){
			newObj=newObj(curObj);
		}
		curObj={
			...newObj,setState,onChange,offChange,refresh
		};
		if(!willRefresh){
			willRefresh=1;
			callAfter$1(refresh);
		}
	}
	function onChange(callback){
		onChangeSet.add(callback);
	}
	function offChange(callback){
		onChangeSet.delete(callback);
	}
	function isTracing(name){
		return !!pMap.get(name);
	}
	onChangeSet=new Set();
	curObj={
		...orgObj,
		setState,onChange,offChange,refresh,isTracing
	};
	proxy=new Proxy(new VFACTState(orgObj),{
		get:function(obj,pName){
			return curObj[pName];
		},
		set:function(obj,pName,val){
			let oldTrace;
			switch(pName){
				case "$owner":
					return true;
			}
			if(oldTrace=pMap.get(pName)){
				oldTrace.untrace();
				pMap.set(pName,null);
			}
			if(val instanceof $PVT){
				val.trace((v)=>{
					curObj[pName]=v;
					if(!willRefresh){
						willRefresh=1;
						callAfter$1(refresh);
					}
				});
				curObj[pName]=val.val;
				pMap.set(pName,val);
			}else {
				curObj[pName]=val;
			}
			if(!willRefresh){
				willRefresh=1;
				callAfter$1(refresh);
			}
			return true;
		}
	});
	return proxy;
};
VFACT.flexState=flexState;

let VFACTAni,vfactAni;
const STATE_NONE=0;
const STATE_READY=1;
const STATE_ANI=2;
const STATE_PAUSED=3;
const STATE_END=4;
const STATE_CANCELED=5;

//---------------------------------------------------------------------------
//Animate base class, all animate is contorled with time:
VFACTAni=function(def=null,obj=null)
{
	if(!def){
		return;
	}
	this.startTime=0;
	this.endTime=0;
	this.state=0;
	this.uiObj=null;
	this.state=STATE_NONE;
	this.OnFinish=null;
	this.OnCanel=null;
	this.initByDef(def);
	//Play:
	this.webAniObj=null;
	this.keyFrames=null;
	this.duration=200;
	this.webAniOpts=null;
	//Callback:
	this.OnFinish=null;
	this.OnCancel=null;
	if(obj){
		this.bind2Obj(obj);
	}
};
vfactAni=VFACTAni.prototype={};

//***************************************************************************
//Register ani type and create ani:
//***************************************************************************
{
	var aniTypeHash = {};

	//---------------------------------------------------------------------------
	//Register an animate type:
	VFACTAni.regAni = function (typeName, func) {
		aniTypeHash[typeName] = func;
	};

	//---------------------------------------------------------------------------
	//Create animate by type:
	VFACTAni.createAniByType = function (typeName, def, obj) {
		let typeType,func,ani;
		typeType=typeof(typeName);
		if(typeType==="string") {
			func = aniTypeHash[typeName];
		}
		ani=new func(def,obj);
		return ani;
	};
	
	VFACTAni.regAni("ani",VFACTAni);
	
	VFACTAni.animate=function(pxy,def,startPlay=true){
		let type,ani;
		type=def.type;
		ani=VFACTAni.createAniByType(type,def,pxy);
		if(def.pause||(!startPlay)){
			return ani;
		}
		ani.start();
		return ani;
	};
}

//***************************************************************************
//API:
//***************************************************************************
{
	//-----------------------------------------------------------------------
	//Init with def:
	vfactAni.initByDef = function (def) {
		if (this.def) {
			console.error("Ani already inited.");
			return;
		}
		this.def = def;
		if (this.uiObj) {
			this.state = STATE_READY;
		}
	};

	//-----------------------------------------------------------------------
	//bind animate with UI-Obj:
	vfactAni.bind2Obj = function (obj) {
		this.uiObj = obj;
		if (obj && this.def) {
			this.styleObj=obj.$_styleObj;
			this.state = STATE_READY;
		}
	};

	//-----------------------------------------------------------------------
	//start animate:
	vfactAni.start = function () {
		let div,def,easing,loop,delay,endDelay;
		let self=this;
		if (this.state !== STATE_READY) {
			console.error("Ani not ready!");
			return;
		}
		def=this.def;
		if(this.setupKeyFrames){
			this.setupKeyFrames();
		}else {
			this.keyFrames=def.keyFrames;
			this.duration=def.duration||def.time||200;
			this.webAniOpts=def.options||null;
			this.OnFinish=def.OnFinish;
			this.OnCancel=def.OnCancel;
		}
		this.startTime = Date.now();
		if(!this.keyFrames){
			this.state=STATE_END;
			this.endTime = this.startTime;
			return;
		}
		this.state = STATE_ANI;
		div=this.uiObj.webObj;
		easing=def.easing;
		let opts=this.webAniOpts||{duration:this.duration};
		if(easing){
			opts.easing=easing;
		}
		loop=def.loop;
		if(loop){
			opts.iterations=loop>0?loop:Infinity;
		}
		delay=def.delay;
		if(delay>0){
			opts.delay=delay;
		}
		endDelay=def.endDelay;
		if(endDelay>0){
			opts.endDelay=endDelay;
		}
		this.webAniObj=div.animate(this.keyFrames,opts);
		//Callback:
		this.webAniObj.onfinish=function(){
			self.OnFinish&&self.OnFinish();
		};
		this.webAniObj.oncancel=function(){
			self.OnCancel&&self.OnCancel();
		};
	};

	//-----------------------------------------------------------------------
	//pause animate:
	vfactAni.pause = function () {
		if(this.state!==STATE_ANI){
			console.error("Ani not playing!");
			return;
		}
		this.webAniObj.pause();
		this.state=STATE_PAUSED;
	};
	//-----------------------------------------------------------------------
	//resume animate:
	vfactAni.resume = function () {
		if(this.state!==STATE_PAUSED){
			console.error("Ani not paused!");
			return;
		}
		this.webAniObj.play();
		this.state=STATE_ANI;
	};
	//-----------------------------------------------------------------------
	//finish animate:
	vfactAni.stop =
	vfactAni.finish = function () {
		if(this.state!==STATE_PAUSED && this.state!==STATE_ANI){
			console.error("Can't stop ani!");
			return;
		}
		this.webAniObj.finish();
		this.webAniObj=null;
		this.state=STATE_END;
	};
	//-----------------------------------------------------------------------
	//cancel animate:
	vfactAni.cancel = function () {
		if(this.state!==STATE_PAUSED && this.state!==STATE_ANI){
			console.error("Can't stop ani!");
			return;
		}
		this.webAniObj.cancel();
		this.webAniObj=null;
		this.state=STATE_CANCELED;
	};
}

//****************************************************************************
//Pose animate:
//****************************************************************************
{
	//------------------------------------------------------------------------
	let AniPose=function(def,obj){
		if(!def)
			return;
		VFACTAni.call(this,def,obj);
	};
	let aniPose=AniPose.prototype=new VFACTAni();
	VFACTAni.regAni("pose",AniPose);
	//------------------------------------------------------------------------
	aniPose.setupKeyFrames=function(){
		let vo1,vo2,x,y,w,h,frames,frame,finFrame;
		let self=this;
		let def=this.def;
		let obj=this.uiObj;
		let webObj=obj.webObj;
		let styleObj=webObj.style;
		let tsfmLineOrg="";
		let tsfmLineTgt="";
		frames=def.frames;
		frame=frames?frames[0]:def;
		finFrame=frames?frames[frames.length-1]:def;
		vo1={};vo2={};
		this.duration=def.duration||def.time||200;
		function def2VO(){
			let vo2={};
			if("x" in def) {
				x = def.x;
				if(x instanceof Function){
					x=x.call(obj);
				}
				vo2.left=(x>=0||x<0)?x+"px":x;
			}
			if("y" in def) {
				y = def.y;
				if(y instanceof Function){
					y=y.call(obj);
				}
				vo1.top=styleObj.top;
				vo2.top=(y>=0||y<0)?y+"px":y;
			}
			if("w" in def) {
				w = def.w;
				if(w instanceof Function){
					w=w.call(obj);
				}
				vo1.width=styleObj.width;
				vo2.width=(w>=0||w<0)?w+"px":w;
			}
			if("h" in def) {
				h = def.h;
				if(h instanceof Function){
					h=h.call(obj);
				}
				vo1.height=styleObj.height;
				vo2.height=(h>=0||h<0)?h+"px":h;
			}
			if("alpha" in def) {
				vo2.opacity = def.alpha;
			}
			if("scale" in def){
				tsfmLineTgt+='scale('+def.scale+') ';
			}else {
				tsfmLineTgt+='scale('+obj.scale+') ';
			}

			if("rotate" in def){
				tsfmLineTgt+='rotate('+def.rotate+'deg)';
			}else {
				tsfmLineTgt+='rotate('+obj.rotate+'deg)';
			}
			vo2.transform = tsfmLineTgt;
			if("offset" in def){
				vo2.offset=def.offet;
			}
			return vo2;
		}
		if("x" in frame) {
			x = frame.x;
			if(x instanceof Function){
				x=x.call(obj);
			}
			vo1.left=styleObj.left;
			vo2.left=(x>=0||x<0)?x+"px":x;
		}
		if("y" in frame) {
			y = frame.y;
			if(y instanceof Function){
				y=y.call(obj);
			}
			vo1.top=styleObj.top;
			vo2.top=(y>=0||y<0)?y+"px":y;
		}
		if("w" in frame) {
			w = frame.w;
			if(w instanceof Function){
				w=w.call(obj);
			}
			vo1.width=styleObj.width;
			vo2.width=(w>=0||w<0)?w+"px":w;
		}
		if("h" in frame) {
			h = frame.h;
			if(h instanceof Function){
				h=h.call(obj);
			}
			vo1.height=styleObj.height;
			vo2.height=(h>=0||h<0)?h+"px":h;
		}
		if("alpha" in frame) {
			vo1.opacity = styleObj.opacity;
			vo2.opacity = frame.alpha;
		}
		//Anchor:
		{
			let ax,ay;
			ax=obj.anchorX;
			ay=obj.anchorY;
			switch(ax){
				case 0:
				default:
					ax="0px";
					break;
				case 1:
					ax="-50%";
					break;
				case 2:
					ax="-100%";
					break;
			}
			switch(ay){
				case 0:
				default:
					ay="0px";
					break;
				case 1:
					ay="-50%";
					break;
				case 2:
					ay="-100%";
					break;
			}
			tsfmLineOrg+=`translate(${ax},${ay}) `;
			tsfmLineTgt+=`translate(${ax},${ay}) `;
		}
		if("scale" in frame){
			tsfmLineOrg+='scale('+obj.scale+') ';
			tsfmLineTgt+='scale('+frame.scale+') ';
		}else {
			tsfmLineOrg+='scale('+obj.scale+') ';
			tsfmLineTgt+='scale('+obj.scale+') ';
		}
		
		if("rotate" in frame){
			tsfmLineOrg+='rotate('+obj.rotate+'deg)';
			tsfmLineTgt+='rotate('+frame.rotate+'deg)';
		}else {
			tsfmLineOrg+='rotate('+obj.rotate+'deg)';
			tsfmLineTgt+='rotate('+obj.rotate+'deg)';
		}
		vo1.transform = tsfmLineOrg;
		vo2.transform = tsfmLineTgt;
		
		this.webAniOpts={
			composite:"replace",duration:this.duration,easing:def.easing
		};
		this.keyFrames=[vo1,vo2];
		if(frames){
			let i,n;
			this.keyFrames=[vo1];
			n=frames.length;
			for(i=1;i<n;i++){
				this.keyFrames.push(def2VO(frames[i]));
			}
			this.keyFrames.push(vo2);
		}else {
			this.keyFrames=[vo1,vo2];
		}
		//Setup OnFinish:
		this.OnFinish=function(){
			if("x" in finFrame){
				obj.x = finFrame.x;
			}
			if("y" in finFrame){
				obj.y = frame.y;
			}
			if("w" in finFrame){
				obj.w = finFrame.w;
			}
			if("h" in finFrame){
				obj.h = finFrame.h;
			}
			if("alpha" in finFrame){
				obj.alpha = finFrame.alpha;
			}
			if("scale" in finFrame){
				obj.scale = finFrame.scale;
			}
			if("rotate" in finFrame){
				obj.rotate = finFrame.rotate;
			}
			if(def.OnFinish){
				def.OnFinish.call(self);
			}
		};
		this.OnCancel=function(){
			if(def.OnCancel){
				def.OnCancel.call(self);
			}
		};
	};
}

//****************************************************************************
//Fade animate:
//****************************************************************************
{
	//------------------------------------------------------------------------
	let AniFade=function(def,obj){
		if(!def)
			return;
		this.actionDir=1;//0:hide,1:show
		VFACTAni.call(this,def,obj);
	};
	let aniFade=AniFade.prototype=new VFACTAni();
	VFACTAni.regAni("fade",AniFade);
	VFACTAni.regAni("show",AniFade);
	VFACTAni.regAni("hide",AniFade);
	VFACTAni.regAni("in",AniFade);
	VFACTAni.regAni("out",AniFade);
	
	//------------------------------------------------------------------------
	aniFade.start=function(){
		this.uiObj.display=true;
		vfactAni.start.call(this);
	};

	//------------------------------------------------------------------------
	aniFade.setupKeyFrames=function(){
		let self=this;
		let def=this.def;
		let obj=this.uiObj;

		switch(def.type){
			case "show":
			case "in":
				obj.display=1;
				this.actionDir=1;
				this.setupAniFrames();
				this.keyFrames=[this.hideKeyFrame,this.showKeyFrame];
				break;
			case "hide":
			case "out":
				if(!obj.display){
					this.keyFrames=null;
					return;
				}
				this.actionDir=0;
				this.setupAniFrames();
				this.keyFrames=[this.showKeyFrame,this.hideKeyFrame];
				break;
			default:
				if(obj.display){
					this.actionDir=0;
					this.setupAniFrames();
					this.keyFrames=[this.showKeyFrame,this.hideKeyFrame];
				}else {
					this.actionDir=1;
					this.setupAniFrames();
					this.keyFrames=[this.hideKeyFrame,this.showKeyFrame];
				}
		}
		this.OnFinish=function(){
			if(self.actionDir===0){
				obj.display=0;
				Object.assign(self.styleObj,self.showKeyFrame);
			}
			if(def.OnFinish){
				def.OnFinish.call(self);
			}
		};
		this.OnCancel=function(){
			if(self.actionDir===0){
				obj.display=1;
				Object.assign(self.styleObj,self.showKeyFrame);
			}else {
				obj.display=0;
				Object.assign(self.styleObj,self.showKeyFrame);
			}
			if(def.OnCancel){
				def.OnCancel.call(self);
			}
		};
	};
	
	//------------------------------------------------------------------------
	aniFade.setupAniFrames=function(){
		let voShow,voHide,x,y,w,h;
		let def=this.def;
		let obj=this.uiObj;
		let webObj=obj.webObj;
		let styleObj=webObj.style;
		let tsfmLineShow="";
		let tsfmLineHide="";
		voShow={};voHide={};
		this.showKeyFrame=voShow;
		this.hideKeyFrame=voHide;
		this.duration=def.duration||def.time||200;
		if("dx" in def){
			x = def.dx;
			if(x instanceof Function){
				x=x.call(obj);
			}
			voShow.left=styleObj.left;
			voHide.left=(obj.x+x)+"px";
		}else {
			if("showX" in def) {
				x = def.showX;
				if(x instanceof Function){
					x=x.call(obj);
				}
				voShow.left=(x>=0||x<0)?x+"px":x;
			}else {
				voShow.left=styleObj.left;
			}
			if("hideX" in def) {
				x = def.hideX;
				if(x instanceof Function){
					x=x.call(obj);
				}
				voHide.left=(x>=0||x<0)?x+"px":x;
			}else {
				voHide.left=styleObj.left;
			}
		}
		
		if("dy" in def){
			y = def.dy;
			if(y instanceof Function){
				y=y.call(obj);
			}
			voShow.top=styleObj.top;
			voHide.top=(obj.y+y)+"px";
		}else {
			if("showY" in def) {
				y = def.showY;
				if(y instanceof Function){
					y=y.call(obj);
				}
				voShow.top=(y>=0||y<0)?y+"px":y;
			}else {
				voShow.top=styleObj.top;
			}
			if("hideY" in def) {
				y = def.hideY;
				if(y instanceof Function){
					y=y.call(obj);
				}
				voHide.top=(y>=0||y<0)?y+"px":y;
			}else {
				voHide.top=styleObj.top;
			}
		}
		
		if("dw" in def){
			w = def.dw;
			if(w instanceof Function){
				w=w.call(obj);
			}
			voShow.width=styleObj.width;
			voHide.width=(obj.w+w)+"px";
		}else {
			if("showW" in def) {
				w = def.showW;
				if(w instanceof Function){
					w=w.call(obj);
				}
				voShow.width=(w>=0||w<0)?w+"px":w;
			}else {
				voShow.width=styleObj.width;
			}
			if("hideW" in def) {
				w = def.hideW;
				if(w instanceof Function){
					w=w.call(obj);
				}
				voHide.width=(w>=0||w<0)?w+"px":w;
			}else {
				voHide.width=styleObj.width;
			}
		}

		if("dh" in def){
			h = def.dh;
			if(h instanceof Function){
				h=h.call(obj);
			}
			voShow.height=styleObj.height;
			voHide.height=(obj.h+h)+"px";
		}else {
			if("showH" in def) {
				h = def.showH;
				if(h instanceof Function){
					h=h.call(obj);
				}
				voShow.height=(h>=0||h<0)?h+"px":h;
			}else {
				voShow.height=styleObj.height;
			}
			if("hideH" in def) {
				h = def.hideH;
				if(h instanceof Function){
					h=h.call(obj);
				}
				voHide.height=(h>=0||h<0)?h+"px":h;
			}else {
				voHide.height=styleObj.height;
			}
		}

		if("alpha" in def) {
			voShow.opacity = styleObj.opacity;
			voHide.opacity = def.alpha;
		}
		
		//Anchor:
		{
			let ax,ay,hCode,vCode;
			ax=obj.anchorX;
			ay=obj.anchorY;
			switch(ax){
				case 0:
				default:
					ax="0px";
					hCode="left";
					break;
				case 1:
					ax="-50%";
					hCode="center";
					break;
				case 2:
					ax="-100%";
					hCode="right";
					break;
			}
			switch(ay){
				case 0:
				default:
					ay="0px";
					vCode="top";
					break;
				case 1:
					ay="-50%";
					vCode="center";
					break;
				case 2:
					ay="-100%";
					vCode="bottom";
					break;
			}
			tsfmLineShow+=`translate(${ax},${ay}) `;
			tsfmLineHide+=`translate(${ax},${ay}) `;
			voShow.transformOrigin=vCode+" "+hCode;
			voHide.transformOrigin=vCode+" "+hCode;
		}
		
		if("scale" in def){
			tsfmLineShow+='scale('+obj.scale+') ';
			tsfmLineHide+='scale('+(def.scale)+') ';
		}else {
			tsfmLineShow+='scale('+obj.scale+') ';
			tsfmLineHide+='scale('+obj.scale+') ';
		}
		
		if("rotate" in def){
			tsfmLineShow+='rotate('+obj.rotate+'deg)';
			tsfmLineHide+='rotate('+def.rotate+'deg)';
		}else {
			tsfmLineShow+='rotate('+obj.rotate+'deg)';
			tsfmLineHide+='rotate('+obj.rotate+'deg)';
		}
		voShow.transform = tsfmLineShow;
		voHide.transform = tsfmLineHide;

		this.webAniOpts={
			composite:"replace",duration:this.duration,easing:def.easing
		};
	};
}

//****************************************************************************
//Auto animate:
//****************************************************************************
{
	//------------------------------------------------------------------------
	let AniAuto=function(def,obj){
		if(!def)
			return;
		this.orgStyle=null;
		this.tgtStyle=null;
		this.orgDisplay=0;
		this.tgtDisplay=0;
		VFACTAni.call(this,def,obj);
	};
	let aniAuto=AniAuto.prototype=new VFACTAni();
	VFACTAni.regAni("auto",AniAuto);

	//------------------------------------------------------------------------
	//-----------------------------------------------------------------------
	//bind animate with UI-Obj:
	aniAuto.bind2Obj = function (obj) {
		let styleObj;
		this.uiObj = obj;
		styleObj=obj.webObj.style;
		this.orgDisplay=obj.display;
		this.orgStyle={
			left:styleObj.left,
			top:styleObj.top,
			width:styleObj.width,
			height:styleObj.height,
			opacity:styleObj.opacity,
			transfrom:styleObj.transform,
		};
		if (this.def) {
			this.state = STATE_READY;
		}
	};
	
	//------------------------------------------------------------------------
	aniAuto.setupKeyFrames=function(){
		let self,obj,styleObj,def,finStyle;
		self=this;
		def=this.def;
		obj=this.uiObj;
		styleObj=obj.webObj.style;
		this.tgtDisplay=obj.display;
		this.tgtStyle={
			left:styleObj.left,
			top:styleObj.top,
			width:styleObj.width,
			height:styleObj.height,
			opacity:styleObj.opacity,
			transfrom:styleObj.transform,
		};
		finStyle={...this.tgtStyle};
		this.duration=def.duration||def.time||200;
		if(this.tgtDisplay===this.orgDisplay && !this.orgDisplay){
			this.keyFrames=null;
			return;
		}
		if(!this.orgDisplay && this.tgtDisplay){
			if(def.fade){
				this.orgStyle.opacity=0;
			}
		}else if(this.orgDisplay  && !this.tgtDisplay){
			if(def.fade){
				this.tgtStyle.opacity=0;
			}
		}
		this.keyFrames=[this.orgStyle,this.tgtStyle];
		//Setup OnFinish:
		this.OnFinish=function(){
			Object.assign(styleObj,finStyle);
			if(def.OnFinish){
				def.OnFinish.call(self);
			}
		};
		this.OnCancel=function(){
			if(def.OnCancel){
				def.OnCancel.call(self);
			}
		};
	};
}

//****************************************************************************
//:shared util functions:
//****************************************************************************
let escapeHTML,unescapeHTML,getTextSize,fixColor$1;
{
	escapeHTML=function (htmlStr) {
		let pts,n;
		htmlStr=htmlStr.replaceAll("&", "&amp;")
			.replaceAll("<", "&lt;")
			.replaceAll(">", "&gt;")
			.replaceAll('"', "&quot;")
			.replaceAll("'", "&#39;")
			.replaceAll("\r", "");
		pts=htmlStr.split("\n");
		n=pts.length;
		if(n>0){
			/*for(i=0;i<n;i++){
				pts[i]='"'+pts[i]+'"';
			}*/
			htmlStr=pts.join("\n<br>\n");
		}
		return htmlStr;
	};
	unescapeHTML=function(htmlStr) {
		return htmlStr.replaceAll("&#39;","'")
			.replaceAll("&quot;",'"')
			.replaceAll("&gt;",">")
			.replaceAll("&lt;","<")
			.replaceAll("&amp;","&");
	};
	
	getTextSize=function(text, webObj) {
		// re-use canvas object for better performance
		let font,styleObj;
		const canvas = getTextSize.canvas || (getTextSize.canvas = document.createElement("canvas"));
		const context = canvas.getContext("2d");
		styleObj=window.getComputedStyle(webObj,null);
		font=`${styleObj.fontWeight} ${styleObj.fontSize} ${styleObj.fontFamily}`;
		context.font = font;
		const metrics = context.measureText(text);
		return [Math.trunc(metrics.width),Math.trunc(metrics.height)];
	};
	fixColor$1=function(v){
		let l;
		v=[...v];
		l=v[4];
		if(l>=0){
			l=l>100?100:l;
			v[0]=(255-v[0])*l/100+v[0];
			v[1]=(255-v[1])*l/100+v[1];
			v[2]=(255-v[2])*l/100+v[2];
		}else if(l<0){
			l=l<-100?-100:l;
			v[0]=v[0]*(100+l)/100;
			v[1]=v[1]*(100+l)/100;
			v[2]=v[2]*(100+l)/100;
		}
		return v;
	};
}
//****************************************************************************
//:System event handlers: mouse up, drag component
//****************************************************************************
let sysAddOnMouseUp,sysRemoveOnMouseUp;
let sysStartDrag;
{
	let body=document.body;
	let sysDragVO=null;
	let sysDragOrgX=0;
	let sysDragOrgY=0;
	let sysOnMouseUpReg=new Set();
	VFACT.sysAddOnMouseUp=sysAddOnMouseUp=function(callback){
		sysOnMouseUpReg.add(callback);
	};
	VFACT.sysRemoveOnMouseUp=sysRemoveOnMouseUp=function(callback){
		sysOnMouseUpReg.delete(callback);
	};
	
	
	//Drag compoent moving:
	VFACT.startDrag=sysStartDrag=function(evt,vo){
		if(sysDragVO){
			let dx,dy;
			dx=evt.x-sysDragOrgX;
			dy=evt.y-sysDragOrgY;
			sysDragVO.OnDone && sysDragVO.OnDone(evt,dx,dy);
		}
		sysDragOrgX=evt.x;
		sysDragOrgY=evt.y;
		sysDragVO=vo;
	};
	VFACT.stopDrag=function(vo){
		if(vo && vo!==sysDragVO){
			return;
		}
		if(sysDragVO){
			sysDragVO.OnDone && sysDragVO.OnDone(null,0,0);
			sysDragVO=null;
		}
	};
	let mup=(evt)=>{
		let callback;
		for(callback of sysOnMouseUpReg){
			callback(evt);
		}
	};
	body.addEventListener("mouseup",mup);
	body.addEventListener("touchstart",mup);
	
	let mmove=(evt)=>{
		if(sysDragVO){
			let dx,dy;
			dx=evt.x-sysDragOrgX;
			dy=evt.y-sysDragOrgY;
			sysDragVO.OnDrag && sysDragVO.OnDrag(evt,dx,dy);
			evt.stopPropagation();
		}
	};
	body.addEventListener("mousemove",mmove,true);
	body.addEventListener("touchmove",mmove,true);
	
	let mupc=(evt)=>{
		if(sysDragVO){
			let dx,dy;
			dx=evt.x-sysDragOrgX;
			dy=evt.y-sysDragOrgY;
			sysDragVO.OnDone && sysDragVO.OnDone(evt,dx,dy);
			evt.stopPropagation();
			sysDragVO=null;
		}
	};
	body.addEventListener("mouseup",mupc,true);
	body.addEventListener("touchend",mupc,true);
	body.addEventListener("touchcancel",mupc,true);
}

let vmcAddRefcount=VFACTObj.vmcAddRefcount;
let vmcRelease=VFACTObj.vmcRelease;

//****************************************************************************
//:Common properties all types shared:
//****************************************************************************
function setupBasic(typeDef){
	//Fast propertie index:
	let pptXIdx=typeDef.allocPptIdx("x",0);
	let pptYIdx=typeDef.allocPptIdx("y",0);
	let pptZIdx=typeDef.allocPptIdx("z");
	let pptWIdx=typeDef.allocPptIdx("w",100);
	let pptHIdx=typeDef.allocPptIdx("h",100);
	let pptMinWIdx=typeDef.allocPptIdx("minW","");
	let pptMinHIdx=typeDef.allocPptIdx("minH","");
	let pptMaxWIdx=typeDef.allocPptIdx("maxW","");
	let pptMaxHIdx=typeDef.allocPptIdx("maxH","");
	let pptLayoutXFuncIdx=typeDef.allocPptIdx("layoutXFunc");
	let pptLayoutYFuncIdx=typeDef.allocPptIdx("layoutYFunc");
	let pptLayoutWFuncIdx=typeDef.allocPptIdx("layoutWFunc");
	let pptLayoutHFuncIdx=typeDef.allocPptIdx("layoutHFunc");
	let pptLayoutMinWFuncIdx=typeDef.allocPptIdx("layoutMinWFunc");
	let pptLayoutMinHFuncIdx=typeDef.allocPptIdx("layoutMinHFunc");
	let pptLayoutMaxWFuncIdx=typeDef.allocPptIdx("layoutMaxWFunc");
	let pptLayoutMaxHFuncIdx=typeDef.allocPptIdx("layoutMaxHFunc");
	let pptAutoLayoutIdx=typeDef.allocPptIdx("autoLayout");
	let pptAXIdx=typeDef.allocPptIdx("anchorX",0);
	let pptAYIdx=typeDef.allocPptIdx("anchorY",0);
	let pptAlphaIdx=typeDef.allocPptIdx("alpha",0);
	let pptRotateIdx=typeDef.allocPptIdx("rotate",0);
	let pptScaleIdx=typeDef.allocPptIdx("scale",1);
	let pptTransformOriginIdx=typeDef.allocPptIdx("transformOrigin","center center");
	let pptMarginIdx=typeDef.allocPptIdx("margin");
	let pptPaddingIdx=typeDef.allocPptIdx("padding");
	let pptTraceSizeIdx=typeDef.allocPptIdx("traceSize",false);
	let pptAspectIdx=typeDef.allocPptIdx("aspect","");
	let pptOnSizeIdx=typeDef.defineIdxOnlyPpt("OnSize",null);
	let pptSizeTracerIdx=typeDef.allocPptIdx("sizeTracer",null);
	let pptOverflowIdx=typeDef.allocPptIdx("overflow",1);
	
	let funcGetMap=typeDef.getMap;
	let funcSetMap=typeDef.setMap;
	
	//Val functions:
	let getParent;
	let _layoutChildren;
	let _maybeLayoutChildren;
	let setPosition,getPosition;
	let setX,getX,setY,getY,setZ,getZ;
	let setW,getW,setH,getH;
	let setAX,getAX,setAY,getAY;
	let setTrsmOrg,getTrsmOrg;
	let setAlpha,getAlpha;
	let setScale,getScale;
	let setRotate,getRotate;
	let setMargin,getMargin;
	let setPadding,getPadding;
	let setOverflow,getOverflow;
	let setStyleClass,getStyleClass,getClassList;
	
	let applyTrsm,applyAnchor;
	let parseLength;
	{
		//------------------------------------------------------------------------
		applyAnchor=applyTrsm=function(valMap){
			let sVal,rVal,line,vCode,hCode,styleObj;
			line="";
			let ax,ay;
			ax=valMap[pptAXIdx];
			ay=valMap[pptAYIdx];
			switch(ax){
				case 0:
				default:
					ax="0px";
					hCode="left";
					break;
				case 1:
					ax="-50%";
					hCode="center";
					break;
				case 2:
					ax="-100%";
					hCode="right";
					break;
			}
			switch(ay){
				case 0:
				default:
					ay="0px";
					vCode="top";
					break;
				case 1:
					ay="-50%";
					vCode="center";
					break;
				case 2:
					ay="-100%";
					vCode="bottom";
					break;
			}
			line+=`translate(${ax},${ay}) `;
			sVal=valMap[pptScaleIdx];
			rVal=valMap[pptRotateIdx];
			if(rVal>0 || rVal<0){
				line+=`rotate(${rVal}deg) `;
			}else if(rVal!==undefined){
				line+=`rotate(${rVal}) `;
			}
			if(sVal>=0||sVal<0){
				line+=`scale(${sVal}) `;
			}else if(Array.isArray(sVal)){
				line+=`scale(${sVal[0]},${sVal[1]}) `;
			}else if(sVal){
				line+=`scale(${sVal}) `;
			}
			
			styleObj=valMap[pptStyleObjIdx];
			styleObj.transform=line;
			styleObj.transformOrigin=vCode+" "+hCode;
		};
	}
	
	//set readOnly but can call set functions:
	funcSetMap.set("children",()=>{});
	funcSetMap.set("attached",()=>{});
	
	//--------------------------------------------------------------------------
	//id, parent, previousSibling, nextSibling, querySelector :
	{
		funcGetMap.set("webObj",function(valMap){
			return valMap[pptWebObjIdx];
		});

		funcGetMap.set("style",function(valMap){
			return valMap[pptStyleObjIdx];
		});

		let setId=function(valMap,val){
			valMap[pptWebObjIdx].id=val;
		};
		let getId=function(valMap){
			return valMap[pptWebObjIdx].id;
		};
		typeDef.definePpt("id",getId,setId,false);
		
		getParent=function(valMap){
			let p;
			let webObj=valMap[pptWebObjIdx];
			p=webObj.parentNode;
			if(p){
				return p.$_pxy;
			}
			return null;
		};
		funcGetMap.set("parent",getParent);
		funcGetMap.set("father",getParent);
		
		let getPre=function(valMap){
			let webObj=valMap[pptWebObjIdx];
			if(webObj) {
				let obj = webObj.previousSibling;
				return obj?obj.$_pxy:null;
			}
			return null;
		};
		funcGetMap.set("previousSibling",getPre);
		
		let getNext=function(valMap){
			let webObj=valMap[pptWebObjIdx];
			if(webObj) {
				let obj = webObj.nextSibling;
				return obj?obj.$_pxy:null;
			}
			return null;
		};
		funcGetMap.set("nextSibling",getNext);
		
		{
			let funcIdx=typeDef.allocPptIdx("querySelector",null);
			let querySelector=function(valMap){
				let func;
				func=valMap[funcIdx];
				if(!func){
					let webObj=valMap[pptWebObjIdx];
					func=valMap[funcIdx]=(selectors,domElement=false)=>{
						let element;
						element=webObj.querySelector(selectors);
						if(domElement){
							return element;
						}
						return element?element.$_pxy:null;
					};
				}
				return func;
			};
			funcGetMap.set("querySelector",querySelector);
		}
		
		//This should goto JAX patch?
		{
			let funcIdx=typeDef.allocPptIdx("getElementById",null);
			let getElementById=function(valMap){
				let func;
				func=valMap[funcIdx];
				if(!func){
					let webObj=valMap[pptWebObjIdx];
					func=valMap[funcIdx]=(searchId)=>{
						let element;
						element=webObj.querySelector("#"+searchId);
						return element?element.$_pxy:null;
					};
				}
				return func;
			};
			funcGetMap.set("getElementById",getElementById);
		}
		
		{
			let funcIdx=typeDef.allocPptIdx("querySelectorAll",null);
			let querySelectorAll=function(valMap){
				let func;
				func=valMap[funcIdx];
				if(!func){
					let webObj=valMap[pptWebObjIdx];
					func=valMap[funcIdx]=(selectors,domElement=false)=>{
						let list;
						list=webObj.querySelector(selectors);
						if(domElement){
							return list;
						}
						let alist=[],item,i,n;
						n=list.length;
						for(i=0;i<n;i++){
							item=list[i].$_pxy;
							if(item){
								alist.push(item);
							}
						}
						return alist;
					};
				}
			};
			funcGetMap.set("querySelectorAll",querySelectorAll);
		}
	}
	
	//addRefCount
	{
		let getRefCount=function(valMap){
			return valMap[pptRefCountIdx];
		};
		funcGetMap.set("refCount",getRefCount);
		
		typeDef.defineFunction("addRefCount",vmcAddRefcount);
		funcGetMap.set("hold",funcGetMap.get("addRefCount"));
	}
	//release
	{
		typeDef.defineFunction("release",vmcRelease);
	}
	
	//--------------------------------------------------------------------------
	//doLayout, autoLayout, layoutChildren, traceSize:
	{
		//-------------------------------------------------------------------
		//ppt autoLayout:
		funcGetMap.set("autoLayout",(valMap)=>{
			return valMap[pptAutoLayoutIdx];
		});
		funcSetMap.set("autoLayout",(valMap,val)=>{
			val=!!val;
			valMap[pptAutoLayoutIdx]=val;
			return val;
		});
		
		//--------------------------------------------------------------------
		//ppt traceSize:
		funcGetMap.set("traceSize",(valMap)=>{
			return valMap[pptTraceSizeIdx];
		});
		funcSetMap.set("traceSize",(valMap,val)=>{
			let tracer,onSize,webObj;
			webObj=valMap[pptWebObjIdx];
			val=!!val;
			if(valMap[pptTraceSizeIdx]===val){
				return;
			}
			valMap[pptTraceSizeIdx]=val;
			if(val){
				tracer=valMap[pptSizeTracerIdx];
				if(!tracer){
					tracer=valMap[pptSizeTracerIdx]=new ResizeObserver(entries=>{
						if(webObj.offsetParent){
							onSize=valMap[pptOnSizeIdx];
							if(onSize){
								onSize.call(valMap[pptProxyIdx]);
							}
							_maybeLayoutChildren.call(valMap);
						}
					});
				}
				tracer.observe(valMap[pptWebObjIdx]);
			}else {
				tracer=valMap[pptSizeTracerIdx];
				if(tracer){
					tracer.unobserve(valMap[pptWebObjIdx]);
				}
			}
		});
		
		//-------------------------------------------------------------------
		//function doLayout():
		typeDef.defineFunction("doLayout",function(){
			let valMap=this;
			let lotFunc,parent,fw,fh,val;
			let oldW,oldH,sizeChanged=0;
			let pxy=valMap[pptProxyIdx];
			let styleObj=valMap[pptStyleObjIdx];
			oldW=valMap[pptWIdx];
			oldH=valMap[pptHIdx];
			parent=getParent(valMap);
			if(!parent){
				return;
			}
			fw=parent.clientW;
			fh=parent.clientH;
			
			lotFunc=valMap[pptLayoutXFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptXIdx]=val;
				if(val>=0||val<0){
					styleObj.left=val+"px";
				}else {
					styleObj.left=val;
				}
			}
			lotFunc=valMap[pptLayoutYFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptYIdx]=val;
				if(val>=0||val<0){
					styleObj.top=val+"px";
				}else {
					styleObj.top=val;
				}
			}
			lotFunc=valMap[pptLayoutMinWFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptMinWIdx]=val;
				if(val>=0||val<0){
					styleObj.minWidth=val+"px";
				}else {
					styleObj.minWidth=val;
				}
			}
			lotFunc=valMap[pptLayoutMaxWFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptMaxWIdx]=val;
				if(val>=0||val<0){
					styleObj.maxWidth=val+"px";
				}else {
					styleObj.maxWidth=val;
				}
			}
			lotFunc=valMap[pptLayoutMinHFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptMinHIdx]=val;
				if(val>=0||val<0){
					styleObj.minHeight=val+"px";
				}else {
					styleObj.minHeight=val;
				}
			}
			lotFunc=valMap[pptLayoutMaxHFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptMaxHIdx]=val;
				if(val>=0||val<0){
					styleObj.maxHeight=val+"px";
				}else {
					styleObj.maxHeight=val;
				}
			}
			lotFunc=valMap[pptLayoutWFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptWIdx]=val;
				if(val>=0||val<0){
					styleObj.width=val+"px";
				}else {
					styleObj.width=val;
				}
				if(val!==oldW){
					sizeChanged=1;
				}
			}
			lotFunc=valMap[pptLayoutHFuncIdx];
			if(lotFunc){
				val=lotFunc.call(pxy,fw,fh);
				valMap[pptHIdx]=val;
				if(val>=0||val<0){
					styleObj.height=val+"px";
				}else {
					styleObj.height=val;
				}
				if(val!==oldH){
					sizeChanged=1;
				}
			}
			//Callafter: layoutChildren
			if(sizeChanged){
				_maybeLayoutChildren.call(valMap);
			}
		});
		
		//-------------------------------------------------------------------
		//function maybeLayoutChildren():
		{
			let pptMaybeLayoutChildren=typeDef.allocPptIdx(null,0);
			_maybeLayoutChildren=function(){
				let valMap=this;
				if(valMap[pptMaybeLayoutChildren]){
					return;
				}
				valMap[pptMaybeLayoutChildren]=1;
				callAfter$1(()=>{
					valMap[pptMaybeLayoutChildren]=0;
					_layoutChildren.call(valMap);
				},0,valMap);
			};
			typeDef.defineFunction("maybeLayoutChildren",_maybeLayoutChildren);
		}
		
		//-------------------------------------------------------------------
		//layoutChildren():
		{
			_layoutChildren=function(){
				let valMap=this;
				let chds,chd,i,n;
				let pxy=valMap[pptProxyIdx];
				if(!pxy)
					return;
				chds=pxy.children;
				if(!chds)
					return;
				n=chds.length;
				for(i=0;i<n;i++){
					chd=chds[i];
					if(chd && chd.autoLayout){
						chd.doLayout();
					}
				}
			};
			typeDef.defineFunction("layoutChildren",_layoutChildren);
		}
	}
	
	//-------------------------------------------------------------------
	//clearChildren()
	{
		typeDef.defineFunction("clearChildren",function(){
			//No child in basic.
		});
	}
	
	//--------------------------------------------------------------------------
	//ppt position:
	{
		setPosition=function(valMap,val){
			valMap[pptStyleObjIdx].position=val;
		};
		getPosition=function(valMap){
			return valMap[pptStyleObjIdx].position;
		};
		typeDef.definePpt("position",getPosition,setPosition,false);
	}
	
	//------------------------------------------------------------------------
	//ppt uiEvent:
	{
	
		let pptUIEventIdx=typeDef.allocPptIdx("uiEvent",1);
		let setUIEvent=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptUIEventIdx]=val;
			switch(val){
				case -1:
				case 0://same with 1?
					styleObj.pointerEvents="none";
					break;
				case 1:
					styleObj.pointerEvents="inherit";
					break;
			}
		};
		let getUIEvent=function(valMap,val){
			return valMap[pptUIEventIdx];
		};
		typeDef.definePpt("uiEvent",getUIEvent,setUIEvent,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt flex:
	{
		let _set=function(valMap,val){
			if(val===true){
				val="1 0 auto";
			}else if(val>0){
				val=val+" 0 auto";
			}
			valMap[pptStyleObjIdx].flex=val;
		};
		let _get=function(valMap){
			return valMap[pptStyleObjIdx].flex;
		};
		typeDef.definePpt("flex",_get,_set,false);
	}

	parseLength=function(valMap,val,funcPptIdx){
		let valType=typeof(val);
		let pxy=valMap[pptProxyIdx];
		if(valType==="function"){
			let pObj,fw,fh;
			pObj=getParent(valMap);
			if(pObj){
				fw=pObj.clientW;
				fh=pObj.clientH;
			}else {
				fw=0;
				fh=0;
			}
			valMap[funcPptIdx]=val;
			val=val.call(pxy,fw,fh);
		}else if(valType==="string"){
			if(val[val.length-1]==="%"){
				valMap[funcPptIdx]=null;
			}else if(val[0]===">"){//Raw HTML length:
				valMap[funcPptIdx]=null;
				val=val.substring(1);
			}else if(val){
				let pObj,fw,fh;
				pObj=getParent(valMap);
				if(pObj){
					fw=pObj.clientW;
					fh=pObj.clientH;
				}else {
					fw=0;
					fh=0;
				}
				try{
					val = new Function("FW", "FH", "return (" + val + ")");
					valMap[funcPptIdx]=val;
					val=val.call(pxy,fw,fh);
				}catch(err){
					val=0;
				}
			}else {
				valMap[funcPptIdx]=null;
				return "";
			}
		}else {
			valMap[funcPptIdx]=null;
		}
		return val;
	};
	//--------------------------------------------------------------------------
	//x,y,z,w,h
	{
		//------------------------------------------------------------------------
		//ppt x:
		{
			setX=function(valMap,val){
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutXFuncIdx);
				valMap[pptXIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.left=val+"px";
				}else {
					styleObj.left=val;
				}
			};
			getX=function(valMap){
				let webObj;
				webObj=valMap[pptWebObjIdx];
				if(webObj.offsetParent){
					return webObj.offsetLeft;
				}
				return valMap[pptXIdx];
			};
			typeDef.definePpt("x",getX,setX,true);
		}
		
		//------------------------------------------------------------------------
		//ppt y:
		{
			setY=function(valMap,val){
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutYFuncIdx);
				valMap[pptYIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.top=val+"px";
				}else {
					styleObj.top=val;
				}
			};
			getY=function(valMap){
				let webObj;
				webObj=valMap[pptWebObjIdx];
				if(webObj.offsetParent){
					return webObj.offsetTop;
				}
				return valMap[pptYIdx];
			};
			typeDef.definePpt("y",getY,setY,true);
		}
		
		//------------------------------------------------------------------------
		//z/zIndex
		{
			let parseInt=window.parseInt;//Faster?
			setZ=function(valMap,val){
				val=parseInt(val);
				if(val>=0 || val<0){
					valMap[pptZIdx]=val;
					valMap[pptStyleObjIdx].zIndex=val;
				}else {
					val="";
					valMap[pptZIdx]=undefined;
					valMap[pptStyleObjIdx].zIndex=val;
				}
			};
			getZ=function(valMap){
				return valMap[pptZIdx];
			};
			typeDef.definePpt("z",getZ,setZ,true);
			typeDef.definePpt("zIndex",getZ,setZ,true);
		}
		
		//------------------------------------------------------------------------
		//ppt w:
		{
			setW=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutWFuncIdx);
				oldVal=valMap[pptWIdx];
				valMap[pptWIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.width=val+"px";
				}else {
					styleObj.width=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			getW=function(valMap){
				let webObj;
				webObj=valMap[pptWebObjIdx];
				if(webObj.offsetParent){
					return webObj.offsetWidth;
				}
				return valMap[pptWIdx];
			};
			typeDef.definePpt("w",getW,setW,true);
			typeDef.definePpt("width",getW,setW,true);
		}
		
		//------------------------------------------------------------------------
		//ppt h:
		{
			setH=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutHFuncIdx);
				oldVal=valMap[pptHIdx];
				valMap[pptHIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.height=val+"px";
				}else {
					styleObj.height=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			getH=function(valMap){
				let webObj;
				webObj=valMap[pptWebObjIdx];
				if(webObj.offsetParent){
					return webObj.offsetHeight;
				}
				return valMap[pptHIdx];
			};
			typeDef.definePpt("h",getH,setH,true);
			typeDef.definePpt("height",getH,setH,true);
		}
		
		//------------------------------------------------------------------------
		//ppt minWidth:
		{
			let setVal=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutMinWFuncIdx);
				oldVal=valMap[pptMinWIdx];
				valMap[pptMinWIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.minWidth=val+"px";
				}else {
					styleObj.minWidth=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			let getVal=function(valMap){
				return valMap[pptMinWIdx];
			};
			typeDef.definePpt("minW",getVal,setVal,true);
			funcGetMap.set("minWidth",funcGetMap.get("minW"));
			funcSetMap.set("minWidth",funcSetMap.get("minW"));
		}

		//------------------------------------------------------------------------
		//ppt maxWidth:
		{
			let setVal=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutMaxWFuncIdx);
				oldVal=valMap[pptMaxWIdx];
				valMap[pptMaxWIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.maxWidth=val+"px";
				}else {
					styleObj.maxWidth=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			let getVal=function(valMap){
				return valMap[pptMaxWIdx];
			};
			typeDef.definePpt("maxW",getVal,setVal,true);
			funcGetMap.set("maxWidth",funcGetMap.get("maxW"));
			funcSetMap.set("maxWidth",funcSetMap.get("maxW"));
		}
		
		//------------------------------------------------------------------------
		//ppt minHeight:
		{
			let setVal=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutMinHFuncIdx);
				oldVal=valMap[pptMinHIdx];
				valMap[pptMinHIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.minHeight=val+"px";
				}else {
					styleObj.minHeight=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			let getVal=function(valMap){
				return valMap[pptMaxHIdx];
			};
			typeDef.definePpt("minH",getVal,setVal,true);
			funcGetMap.set("minHeight",funcGetMap.get("minH"));
			funcSetMap.set("minHeight",funcSetMap.get("minH"));
		}

		//------------------------------------------------------------------------
		//ppt maxHeight:
		{
			let setVal=function(valMap,val){
				let oldVal;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				val=parseLength(valMap,val,pptLayoutMaxHFuncIdx);
				oldVal=valMap[pptMaxHIdx];
				valMap[pptMaxHIdx]=val;
				if(val>0||val<0||val===0){
					styleObj.maxHeight=val+"px";
				}else {
					styleObj.maxHeight=val;
				}
				if(oldVal!==val){
					_maybeLayoutChildren.call(valMap);
				}
			};
			let getVal=function(valMap){
				return valMap[pptMaxHIdx];
			};
			typeDef.definePpt("maxH",getVal,setVal,true);
			funcGetMap.set("maxHeight",funcGetMap.get("maxH"));
			funcSetMap.set("maxHeight",funcSetMap.get("maxH"));
		}
	}
	
	//--------------------------------------------------------------------------
	//ppt clientWidth, clientHeight:
	{
		//------------------------------------------------------------------------
		let getClientW=function(valMap){
			let w;
			let webObj;
			webObj=valMap[pptWebObjIdx];
			if(webObj.offsetParent){
				return webObj.clientWidth;
			}
			w=valMap[pptWIdx];
			//TODO: apply border and padding:
			return w>=0?w:0;
		};
		funcGetMap.set("clientW",getClientW);
		funcGetMap.set("clientWidth",getClientW);
		
		//------------------------------------------------------------------------
		let getClientH=function(valMap){
			let h;
			let webObj;
			webObj=valMap[pptWebObjIdx];
			if(webObj.offsetParent){
				return webObj.clientHeight;
			}
			h=valMap[pptHIdx];
			//TODO: apply border and padding:
			return h>=0?h:0;
		};
		funcGetMap.set("clientH",getClientH);
		funcGetMap.set("clientHeight",getClientH);
		
		typeDef.defineFunction("getBoundingClientRect",function(){
			let valMap=this;
			let webObj=valMap[pptWebObjIdx];
			return webObj.getBoundingClientRect();
		});
	}
	
	//--------------------------------------------------------------------------
	//ppt anchorX:
	{
		setAX=function(valMap,val){
			switch(val){
				case 0:
				case 1:
				case 2:
					break;
				case "l":
				case "left":{
					val=0;
					break;
				}
				case "c":
				case "center":{
					val=1;
					break;
				}
				case "r":
				case "right":{
					val=2;
					break;
				}
				default:
					val=0;
					break;
				
			}
			valMap[pptAXIdx]=val;
			applyAnchor(valMap);
		};
		getAX=function(valMap){
			return valMap[pptAXIdx];
		};
		typeDef.definePpt("anchorX",getAX,setAX,true);
		funcGetMap.set("anchorH",funcGetMap.get("anchorX"));
		funcSetMap.set("anchorH",funcSetMap.get("anchorX"));
	}
	
	//--------------------------------------------------------------------------
	//ppt anchorY:
	{
		setAY=function(valMap,val){
			switch(val){
				case 0:
				case 1:
				case 2:
					break;
				case "t":
				case "top":{
					val=0;
					break;
				}
				case "c":
				case "center":{
					val=1;
					break;
				}
				case "b":
				case "bottom":{
					val=2;
					break;
				}
				default:
					val=0;
					break;
				
			}
			valMap[pptAYIdx]=val;
			applyAnchor(valMap);
		};
		getAY=function(valMap){
			return valMap[pptAYIdx];
		};
		typeDef.definePpt("anchorY",getAY,setAY,true);
		funcGetMap.set("anchorV",funcGetMap.get("anchorY"));
		funcSetMap.set("anchorV",funcSetMap.get("anchorY"));
	}
	
	//--------------------------------------------------------------------------
	//ppt transform-origin
	{
		setTrsmOrg=function(valMap,val){
			valMap[pptTransformOriginIdx]=val;
			valMap[pptStyleObjIdx].transformOrigin=val;
		};
		getTrsmOrg=function(valMap){
			return valMap[pptTransformOriginIdx];
		};
		typeDef.definePpt("transformOrigin",getTrsmOrg,setTrsmOrg,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt display
	{
		let _set=function(valMap,val){
			val=!!val;
			valMap[pptDisplayIdx]=val;
			valMap[pptStyleObjIdx].display=val?valMap[pptDisplayCodeIdx]:"none";
		};
		let _get=function(valMap){
			return valMap[pptDisplayIdx];
		};
		typeDef.definePpt("display",_get,_set,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt alpha:
	{
		setAlpha=function(valMap,val){
			valMap[pptAlphaIdx]=val;
			valMap[pptStyleObjIdx].opacity=val;
		};
		getAlpha=function(valMap){
			return valMap[pptAlphaIdx];
		};
		typeDef.definePpt("alpha",getAlpha,setAlpha,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt scale:
	{
		setScale=function(valMap,val){
			valMap[pptScaleIdx]=val;
			applyTrsm(valMap);
		};
		getScale=function(valMap){
			return valMap[pptScaleIdx];
		};
		typeDef.definePpt("scale",getScale,setScale,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt rotate:
	{
		setRotate=function(valMap,val){
			valMap[pptRotateIdx]=val;
			applyTrsm(valMap);
		};
		getRotate=function(valMap){
			return valMap[pptRotateIdx];
		};
		typeDef.definePpt("rotate",getRotate,setRotate,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt cursor, aspect, filter:
	{
		let setCursor=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			styleObj.cursor=val;
			return styleObj.cursor;
		};
		let getCursor=function(valMap){
			return valMap[pptStyleObjIdx].cursor;
		};
		typeDef.definePpt("cursor",getCursor,setCursor,true);
		
		let setAspect=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptAspectIdx]=val;
			styleObj.aspectRatio=val;
			return styleObj.val;
		};
		let getAspect=function(valMap,val){
			return valMap[pptAspectIdx];
		};
		typeDef.definePpt("aspect",getAspect,setAspect,true);
		
		let setFilter=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			styleObj.filter=val;
			return styleObj.filter;
		};
		let getFilter=function(valMap){
			return valMap[pptStyleObjIdx].filter;
		};
		typeDef.definePpt("filter",getFilter,setFilter,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt margin:
	{
		setMargin=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptMarginIdx]=val;
			if(Array.isArray(val)){
				styleObj.margin=`${val[0]}px ${val[1]}px ${val[2]}px ${val[3]}px`;
			}else if(val>=0 || val<0){
				styleObj.margin=val+"px";
			}else {
				styleObj.margin=val||"";
			}
		};
		getMargin=function(valMap){
			return valMap[pptMarginIdx];
		};
		typeDef.definePpt("margin",getMargin,setMargin,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt padding:
	{
		setPadding=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptPaddingIdx]=val;
			if(Array.isArray(val)){
				styleObj.padding=`${val[0]}px ${val[1]}px ${val[2]}px ${val[3]}px`;
			}else if(val>=0 || val<0){
				styleObj.padding=val+"px";
			}else {
				styleObj.padding=val||"";
			}
		};
		getPadding=function(valMap){
			return valMap[pptPaddingIdx];
		};
		typeDef.definePpt("padding",getPadding,setPadding,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt overflow:
	{
		setOverflow=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptOverflowIdx]=val;
			if(Array.isArray(val)){
				let code;
				switch(val[0]){
					case 1:
					case "hidden":
					case "clip":
						code="hidden ";
						break;
					case 0:
					case "visible":
					case "show":
						code="visible ";
						break;
					case "scroll":
					case 2:
						code="scroll ";
						break;
					case "auto":
					case 3:
						code="auto ";
						break;
				}
				switch(val[1]){
					case 1:
					case "hidden":
					case "clip":
						code+="hidden";
						break;
					case 0:
					case "visible":
					case "show":
						code+="visible";
						break;
					case "scroll":
					case 2:
						code+="scroll";
						break;
					case "auto":
					case 3:
						code+="auto";
						break;
				}
				styleObj.overflow=code;
			}else {
				switch(val){
					case 1:
					case "hidden":
					case "clip":
						styleObj.overflow="hidden";
						break;
					case 0:
					case "visible":
					case "show":
						styleObj.overflow="visible";
						break;
					case "scroll":
						styleObj.overflow="scroll";
						break;
					case "auto":
						styleObj.overflow="auto";
						break;
					case "scroll-x":
						styleObj.overflow="scroll hidden";
						break;
					case "scroll-y":
						styleObj.overflow="hidden scroll";
						break;
					case "auto-x":
						styleObj.overflow="auto hidden";
						break;
					case "auto-y":
						styleObj.overflow="hidden auto";
						break;
					default:
						styleObj.overflow=val;
						break;
				}
			}
		};
		getOverflow=function(valMap){
			return valMap[pptOverflowIdx];
		};
		typeDef.definePpt("overflow",getOverflow,setOverflow,true);
	}
	
	//------------------------------------------------------------------------
	//style class list
	{
		setStyleClass=function(valMap,val){
			let classList,items;
			let webObj=valMap[pptWebObjIdx];
			classList=webObj.classList;
			//Clear old list:
			items=Array.from(classList.values());
			classList.remove.apply(classList,items);
			if(!val){
				return;
			}
			if(typeof(val)==="string"){
				val=val.split(" ");
			}else if(!Array.isArray(val)){
				val=[val];
			}
			if(val && val.length){
				classList.add.apply(classList,val);
			}
		};
		getStyleClass=function(valMap){
			let webObj=valMap[pptWebObjIdx];
			return webObj.classList.value;
		};
		getClassList=function(valMap){
			let webObj=valMap[pptWebObjIdx];
			return webObj.classList;
		};
		typeDef.definePpt("styleClass",getStyleClass,setStyleClass,false);
		typeDef.definePpt("classList",getClassList,setStyleClass,false);
	}
	
	//------------------------------------------------------------------------
	//animate(def)
	if(VFACT.animate){
		let animate=VFACT.animate;
		typeDef.defineFunction("animate",function(def,startPlay=true){
			let valMap=this;
			let pxy=valMap[pptProxyIdx];
			return animate(pxy,def,startPlay);
		});
	}
	
	//------------------------------------------------------------------------
	//getBoundingClientRect()
	typeDef.defineFunction("getBoundingClientRect",function(){
		let valMap=this;
		let webObj=valMap[pptWebObjIdx];
		return webObj.getBoundingClientRect();
	});
}
VFACTObj.setupBasic=setupBasic;

//****************************************************************************
//:Init basic mouse click:
//****************************************************************************
function setupClick(typeDef){
	let getMap=typeDef.getMap;
	let setMap=typeDef.setMap;

	let pptOnClickIdx=typeDef.allocPptIdx("OnClick",null);
	let pptOnTreeClickIdx=typeDef.allocPptIdx("OnTreeClick",null);
	let _OnClick=function(valMap,evt){
		let webObj,pxy,callback;
		webObj=valMap[pptWebObjIdx];
		pxy=valMap[pptProxyIdx];
		if(evt.target===webObj){
			evt.stopPropagation();
			callback=valMap[pptOnClickIdx];
			if(callback){
				callback.call(pxy,evt);
			}
		}else {
			evt.stopPropagation();
			callback=valMap[pptOnTreeClickIdx];
			if(callback){
				callback.call(pxy,evt);
			}
		}
	};
	//-----------------------------------------------------------------------
	//ppt OnClick:
	{
		let _set=function(valMap,val){
			let callback;
			let webObj=valMap[pptWebObjIdx];
			valMap[pptOnClickIdx]=val;
			callback=valMap[pptOnTreeClickIdx];
			if(!val && !callback){
				webObj.onclick=null;
			}else {
				webObj.onclick=(evt)=>{
					_OnClick(valMap,evt);
				};
			}
		};
		let _get=function(valMap){
			return valMap[pptOnClickIdx];
		};
		getMap.set("OnClick",_get);
		setMap.set("OnClick",_set);
		
	}
	
	//-----------------------------------------------------------------------
	//ppt OnTreeClick:
	{
		let _set=function(valMap,val){
			let callback;
			let webObj=valMap[pptWebObjIdx];
			valMap[pptOnTreeClickIdx]=val;
			callback=valMap[pptOnClickIdx];
			if(!val && !callback){
				webObj.onclick=null;
			}else {
				webObj.onclick=(evt)=>{
					_OnClick(valMap,evt);
				};
			}
		};
		let _get=function(valMap){
			return valMap[pptOnTreeClickIdx];
		};
		getMap.set("OnTreeClick",_get);
		setMap.set("OnTreeClick",_set);
	}

	//-----------------------------------------------------------------------
	//ppt OnMouseInOut:
	{
		let pptOnMouseInOutIdx=typeDef.allocPptIdx("OnMouseInOut",null);
		let _MouseInOut=function(valMap,inout,evt){
			let callback=valMap[pptOnMouseInOutIdx];
			if(callback){
				callback.call(valMap[pptProxyIdx],inout,evt);
			}
		};
		let _set=function(valMap,val){
			let webObj=valMap[pptWebObjIdx];
			valMap[pptOnMouseInOutIdx]=val;
			if(!val){
				webObj.onmouseenter=null;
				webObj.onmouseleave=null;
			}else {
				webObj.onmouseenter=(evt)=>{
					_MouseInOut(valMap,1,evt);
				};
				webObj.onmouseleave=(evt)=>{
					_MouseInOut(valMap,0,evt);
				};
			}
		};
		let _get=function(valMap){
			return valMap[pptOnMouseInOutIdx];
		};
		getMap.set("OnMouseInOut",_get);
		setMap.set("OnMouseInOut",_set);
	}
}
VFACTObj.setupClick=setupClick;

//****************************************************************************
//:Init hierarchy features:
//****************************************************************************
function setupHierarchy(typeDef){
	let funcGetMap=typeDef.getMap;
	let funcSetMap=typeDef.setMap;
	
	let pptContentLayoutIdx=typeDef.allocPptIdx("contentLayout","");
	let pptGridConfigIdx=typeDef.allocPptIdx("gridConfig","");
	let pptSubAlignIdx=typeDef.allocPptIdx("subAlign",0);
	let pptItemsAlignIdx=typeDef.allocPptIdx("itemsAlign",0);
	let pptItemsWrapIdx=typeDef.allocPptIdx("itemsWrap",0);
	let applyLayout;

	//-----------------------------------------------------------------------
	applyLayout=function(valMap){
		let layout,styleObj,display,code;
		styleObj=valMap[pptStyleObjIdx];
		layout=valMap[pptContentLayoutIdx];
		switch(layout){
			case "flex":
			case "flex-x":
			case "flexX":
				code=valMap[pptDisplayCodeIdx]="flex";
				styleObj.flexDirection="row";
				break;
			case "flexXr":
			case "flex-xr":
				code=valMap[pptDisplayCodeIdx]="flex";
				styleObj.flexDirection="row-reverse";
				break;
			case "flex-y":
			case "flexY":
				code=valMap[pptDisplayCodeIdx]="flex";
				styleObj.flexDirection="column";
				break;
			case "flexYr":
			case "flex-yr":
				code=valMap[pptDisplayCodeIdx]="flex";
				styleObj.flexDirection="column-reverse";
				break;
			case "grid":
				code=valMap[pptDisplayCodeIdx]="grid";
				break;
		}
		display=valMap[pptDisplayIdx];
		if(display){
			styleObj.display=code;
		}
	};
	
	//-----------------------------------------------------------------------
	//runtime properties:
	{
		//-------------------------------------------------------------------
		//ppt contentLayout:
		{
			let _set=function(valMap,val){
				valMap[pptContentLayoutIdx]=val;
				applyLayout(valMap);
			};
			let _get=function(valMap) {
				return valMap[pptContentLayoutIdx];
			};
			typeDef.definePpt("contentLayout",_get,_set,true);
		}

		//-------------------------------------------------------------------
		//ppt subAlign:
		{
			let _set=function(valMap,val){
				let styleObj;
				valMap[pptSubAlignIdx]=val;
				styleObj=valMap[pptStyleObjIdx];
				switch(val){
					case 0:
						styleObj.justifyContent="flex-start";
						break;
					case 1:
						styleObj.justifyContent="center";
						break;
					case 2:
						styleObj.justifyContent="flex-end";
						break;
					case 3:
						styleObj.justifyContent="space-around";
						break;
					case 4:
						styleObj.justifyContent="space-evenly";
						break;
					case 4:
						styleObj.justifyContent="space-between";
						break;
					default:
						styleObj.justifyContent=val;
						break;
				}
			};
			let _get=function(valMap) {
				return valMap[pptSubAlignIdx];
			};
			typeDef.definePpt("subAlign",_get,_set,true);
		}

		//-------------------------------------------------------------------
		//ppt itemsAlign:
		{
			let _set=function(valMap,val){
				let styleObj;
				valMap[pptItemsAlignIdx]=val;
				styleObj=valMap[pptStyleObjIdx];
				switch(val){
					case 0:
						styleObj.alignItems="start";
						break;
					case 1:
						styleObj.alignItems="center";
						break;
					case 2:
						styleObj.alignItems="flex-end";
						break;
					default:
						styleObj.alignItems=val;
						break;
				}
			};
			let _get=function(valMap) {
				return valMap[pptItemsAlignIdx];
			};
			typeDef.definePpt("itemsAlign",_get,_set,true);
		}

		//-------------------------------------------------------------------
		//ppt itemsWrap:
		{
			let _set=function(valMap,val){
				let styleObj;
				valMap[pptItemsWrapIdx]=val;
				styleObj=valMap[pptStyleObjIdx];
				switch(val){
					case 0:
					case false:
						styleObj.flexWrap="nowrap";
						break;
					case 1:
					case true:
						styleObj.flexWrap="wrap";
						break;
					case 2:
						styleObj.flexWrap="wrap-reverse";
						break;
					default:
						styleObj.alignItems=val;
						break;
				}
			};
			let _get=function(valMap) {
				return valMap[pptItemsWrapIdx];
			};
			typeDef.definePpt("itemsWrap",_get,_set,true);
		}

		//-------------------------------------------------------------------
		//ppt gridConfig:
		{
			let _set=function(valMap,val){
				let styleObj;
				valMap[pptGridConfigIdx]=val;
				styleObj=valMap[pptStyleObjIdx];
				if(Array.isArray((val))){
					if(val.length===2){
						styleObj.gridTemplateColumns=val[0]||"";
						styleObj.gridTemplateRows=val[1]||"";
					}else {
						styleObj.gridTemplateAreas=val[0]||"";
						styleObj.gridTemplateColumns=val[1]||"";
						styleObj.gridTemplateRows=val[2]||"";
					}
				}else {
					styleObj.gridTemplateColumns=val;
				}
			};
			let _get=function(valMap) {
				return valMap[pptGridConfigIdx];
			};
			typeDef.definePpt("gridConfig",_get,_set,true);
		}

		//-------------------------------------------------------------------
		let getFirstChild=function(valMap){
			let obj;
			obj=valMap[pptWebObjIdx].firstChild;
			return obj?obj.$_pxy:null;
		};
		funcGetMap.set("firstChild",getFirstChild);
		
		//------------------------------------------------------------------------
		let getLastChild=function(valMap){
			let element;
			element=valMap[pptWebObjIdx].lastChild;
			return element?element.$_pxy:null;
		};
		funcGetMap.set("lastChild",getLastChild);
		
		//------------------------------------------------------------------------
		let getChildList=function(valMap){
			let childPxy,chNdList;
			childPxy=valMap[pptChildrenIdx];
			if(childPxy){
				return childPxy;
			}
			chNdList=valMap[pptWebObjIdx].childNodes;
			childPxy=new Proxy(chNdList,{
				get:function(obj,pname){
					if(pname>=0){
						let node;
						node=obj[pname];
						if(!node){
							return null;
						}else {
							return node.$_pxy;
						}
					}
					return obj[pname];
				}
			});
			valMap[pptChildrenIdx]=childPxy;
			return childPxy;
		};
		funcGetMap.set("children",getChildList);
		funcSetMap.set("children",()=>{});
	}
	
	//--------------------------------------------------------------------------
	//runtime function
	{
		//-------------------------------------------------------------------
		//appendChild
		{
			typeDef.defineFunction("appendChild",function(obj){
				let valMap=this;
				let subWebObj,prePrt;
				subWebObj=obj.$_webObj;
				prePrt=subWebObj.parentNode;
				if(prePrt){
					prePrt=prePrt.$_pxy;
				}
				valMap[pptWebObjIdx].appendChild(subWebObj);
				obj.doLayout();
				if(!prePrt){
					obj.addRefCount();
				}
				return obj;
			});
		}
		
		//-------------------------------------------------------------------
		//appendNewChild
		{
			typeDef.defineFunction("appendNewChild",function(def){
				let valMap=this;
				if(Array.isArray(def)){
					let item;
					for(item of def){
						VFACT.createObj(item, valMap[pptProxyIdx]);
					}
					return;
				}
				return VFACT.createObj(def, valMap[pptProxyIdx]);
			});
		}
		
		//-------------------------------------------------------------------
		//insertBefore
		{
			typeDef.defineFunction("insertBefore",function(obj1,obj2){
				let valMap=this;
				let webObj1,prePrt;
				webObj1=obj1.$_webObj;
				prePrt=webObj1.parentNode;
				if(prePrt){
					prePrt=prePrt.$_pxy;
				}
				valMap[pptWebObjIdx].insertBefore(webObj1,obj2.$_webObj);
				obj1.doLayout();
				if(!prePrt){
					obj1.addRefCount();
				}
				return obj1;
			});
		}
		
		//-------------------------------------------------------------------
		//insertNewBefore
		{
			typeDef.defineFunction("insertNewBefore",function(def,obj){
				let valMap=this;
				return VFACT.createObj(def, valMap[pptProxyIdx],obj);
			});
		}

		//-------------------------------------------------------------------
		//removeChild
		{
			typeDef.defineFunction("removeChild",function(obj){
				let valMap=this;
				valMap[pptWebObjIdx].removeChild(obj.$_webObj);
				//dec-refcount:
				obj.release();
			});
		}
		
		//-------------------------------------------------------------------
		//replaceChild
		{
			typeDef.defineFunction("replaceChild",function(obj1,obj2){
				let valMap=this;
				let webObj1,prePrt;
				if(obj1===obj2){
					return;
				}
				webObj1=obj1.$_webObj;
				prePrt=webObj1.parentNode;
				if(prePrt){
					prePrt=prePrt.$_pxy;
				}
				obj1=valMap[pptWebObjIdx].replaceChild(webObj1,obj2.$_webObj);
				obj1.doLayout();
				//inc/dec-refcount:
				if(!prePrt){
					obj1.addRefCount();
				}
				obj2.release();
				return obj1;
			});
		}
		
		//-------------------------------------------------------------------
		//clearChildren
		{
			typeDef.defineFunction("clearChildren",function(){
				let valMap=this;
				let obj,pxy;
				let webObj=valMap[pptWebObjIdx];
				while(obj=webObj.firstChild){
					webObj.removeChild(obj);
					pxy=obj.$_pxy;
					if(pxy){
						pxy.release();
					}
				}
			});
		}
		
		//-------------------------------------------------------------------
		//execInTree
		{
			typeDef.defineFunction("execInTree",function(func){
				let valMap=this;
				let list,i,n,subObj,subExec;
				func(valMap[pptProxyIdx]);
				list=valMap[pptWebObjIdx].childNodes;
				n=list.length;
				for(i=0;i<n;i++){
					subObj=list[i].$_pxy;
					if(subObj){
						subExec=subObj.execInTree;
						if(subExec){
							subExec.call(subObj,func);
						}else {
							func(subObj);
						}
					}
				}
			});
		}
	}
}
VFACTObj.setupHierarchy=setupHierarchy;

const emptyList=[];
function setupNoneHierarchy(typeDef){
	let funcGetMap=typeDef.getMap;
	let funcSetMap=typeDef.setMap;

	//-----------------------------------------------------------------------
	//runtime properties:
	{
		//-------------------------------------------------------------------
		let getFirstChild=function(valMap){
			return null;
		};
		funcGetMap.set("firstChild",getFirstChild);
		
		//------------------------------------------------------------------------
		let getLastChild=function(valMap){
			let element;
			element=valMap[pptWebObjIdx].lastChild;
			return element?element.$_pxy:null;
		};
		funcGetMap.set("lastChild",getLastChild);
		
		//------------------------------------------------------------------------
		let getChildList=function(valMap){
			return emptyList;
		};
		funcGetMap.set("children",getChildList);
		funcSetMap.set("children",()=>{});
	}
	
	//--------------------------------------------------------------------------
	//runtime function
	{
		//-------------------------------------------------------------------
		//execInTree
		{
			typeDef.defineFunction("execInTree",function(func){
				let valMap=this;
				func(valMap[pptProxyIdx]);
			});
		}
	}
}
VFACTObj.setupNoneHierarchy=setupNoneHierarchy;

//****************************************************************************
//:Init faces features:
//****************************************************************************
function setupFaces(typeDef){
	let funcGetMap=typeDef.getMap;
	let funcSetMap=typeDef.setMap;
	
	let pptCurFaceIdx=typeDef.allocPptIdx("curFace","");
	let _setFace=function(faceName,vo){
		let valMap=this;
		let faces,faceVO,nameType;
		let pxy=valMap[pptProxyIdx];
		
		function applyFace(fvo){
			let name,obj,ppts;
			for(name in fvo){
				ppts=fvo[name];
				if(typeof(ppts)==="function"){
					if(ppts.call(pxy,vo)===false){
						return;
					}
				}else if(name[0]==="@"){
					let vo=ppts;
					window.setTimeout(()=>{
						applyFace(vo);
					},parseInt(name.substring(1)));
				}else {
					obj=pxy[name];
					if(obj){
						let def,orgAnis,curAnis,i,n,ani;
						orgAnis=ppts.ani;
						if(orgAnis){
							curAnis=[];
							n=orgAnis.length;
							for(i=0;i<n;i++){
								def=orgAnis[i];
								if(def.type==="auto"){
									curAnis[i]=obj.animate(def,false);
								}
							}
						}
						for(let ppt in ppts){
							if(ppt==="ani");else {
								obj[ppt]=ppts[ppt];
							}
						}
						if(orgAnis){
							for(i=0;i<n;i++){
								ani=curAnis[i];
								if(ani){
									ani.start();
								}else {
									obj.animate(orgAnis[i]);
								}
							}
						}
					}/*else{
						console.warn("Missing face target: "+name);
					}*/
				}
			}
		}
		if(!pxy){
			return;
		}
		faces=pxy.faces;
		if(!faces){
			return;
		}
		nameType=typeof(faceName);
		if(Array.isArray(faceName)){
			for(let face of faceName){
				_setFace.call(valMap,face);
			}
			return;
		}else if(nameType==="object"){
			faceVO=faceName;
		}else if(nameType==="string"){
			valMap[pptCurFaceIdx]=faceName;
			faceVO=faces[faceName];
		}
		if(faceVO){
			applyFace(faceVO);
		}
	};
	typeDef.defineFunction("setFace",_setFace);
	funcGetMap.set("showFace",funcGetMap.get("setFace"));
	funcSetMap.set("face",function(valMap,faceName){
		_setFace.call(valMap,faceName);
	});
	funcGetMap.set("face",function(valMap){
		return valMap[pptCurFaceIdx];
	});
}
VFACTObj.setupFaces=setupFaces;

//****************************************************************************
//:Init box properties:
//****************************************************************************
function setupBox(typeDef,bgColor){
	let funcGetMap=typeDef.getMap;
	typeDef.setMap;
	
	//background, border, box-Shadow, mask, etc...
	let pptBackgroundIdx=typeDef.allocPptIdx("background",bgColor);
	let pptCornerIdx=typeDef.allocPptIdx("corner",0);
	let pptBorderIdx=typeDef.allocPptIdx("border",0);
	let pptBorderColorIdx=typeDef.allocPptIdx("borderColor","#000000");
	let pptBorderStyleIdx=typeDef.allocPptIdx("borderStyle","none");
	let pptShadowIdx=typeDef.allocPptIdx("shadow",false);
	let pptShadowXIdx=typeDef.allocPptIdx("shadowX",1);
	let pptShadowYIdx=typeDef.allocPptIdx("shadowY",1);
	let pptShadowBlurIdx=typeDef.allocPptIdx("shadowBlur",2);
	let pptShadowSpreadIdx=typeDef.allocPptIdx("shadowSpread",0);
	let pptShadowColorIdx=typeDef.allocPptIdx("shadowColor",[0,0,0,0.5]);
	let pptShadowInsetIdx=typeDef.allocPptIdx("shadowInset",0);
	let pptMaskImageIdx=typeDef.allocPptIdx("maskImage",undefined);
	
	let setBackground,getBackground;
	let setCorner,getCorner;
	let setBorder,getBorder;
	let setBorderStyle,getBorderStyle;
	let applyShadow;
	let setShadow,getShadow;
	let setShadowX,getShadowX;
	let setShadowY,getShadowY;
	let setShadowBlur,getShadowBlur;
	let setShadowSpread,getShadowSpread;
	let setShadowInset,getShadowInset;
	let setShadowColor,getShadowColor;
	let setMaskImage,getMaskImage;
	
	Object.assign(typeDef.initStyle,{
		background:bgColor,
		borderStyle:"solid",
		borderWidth:"0px",
	});
	
	//--------------------------------------------------------------------------
	//ppt background:
	{
		setBackground=function(valMap,val){
			if(Array.isArray(val)){
				if(val.length>4){
					val=fixColor$1(val);
				}else {
					val=[...val];
				}
				valMap[pptBackgroundIdx]=val;
				val=`rgba(${val[0]||0},${val[1]||0},${val[2]||0},${val[3]>=0?val[3]:1})`;
			}else {
				valMap[pptBackgroundIdx]=val;
			}
			valMap[pptStyleObjIdx].background=val;
		};
		getBackground=function(valMap){
			return valMap[pptBackgroundIdx];
		};
		typeDef.definePpt("background",getBackground,setBackground,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt corner:
	{
		setCorner=function(valMap,val){
			valMap[pptCornerIdx]=val;
			if(val>=0||val<0){
				val=val+"px";
			}else if(Array.isArray(val)){
				val=`${val[0]||0}px ${val[1]||0}px ${val[2]||0}px ${val[3]||0}px`;
			}
			valMap[pptStyleObjIdx].borderRadius=val;
		};
		getCorner=function(valMap){
			return valMap[pptCornerIdx];
		};
		typeDef.definePpt("corner",getCorner,setCorner,true);
	}
	
	//------------------------------------------------------------------------
	//ppt outline:
	{
		let setOutline=function(valMap,val){
			valMap[pptStyleObjIdx].outlineStyle = val?"auto":"none";
		};
		let getOutline=function(valMap){
			return valMap[pptStyleObjIdx].outlineStyle==="none"?0:1;
		};
		typeDef.definePpt("outline",getOutline,setOutline,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt border:
	{
		setBorder=function(valMap,val){
			valMap[pptBorderIdx]=val;
			if(val>=0||val<0){
				val=val+"px";
			}else if(Array.isArray(val)){
				val=`${val[0]||0}px ${val[1]||0}px ${val[2]||0}px ${val[3]||0}px`;
			}
			valMap[pptStyleObjIdx].borderWidth=val;
		};
		getBorder=function(valMap){
			return valMap[pptBorderIdx];
		};
		typeDef.definePpt("border",getBorder,setBorder,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt borderColor:
	{
		//----------------------------------------------------------------------
		let set_=function(valMap,val){
			if(Array.isArray(val)){
				let r;
				val=[...val];
				r=val[0];
				if(r>=0){
					if(val.length>4){
						val=fixColor$1(val);
					}
					valMap[pptBorderColorIdx]=val;
					val=`rgba(${val[0]},${val[1]},${val[2]}, ${val[3]>=0?val[3]:1})`;
				}else if(Array.isArray(r)){
					if(val[0].length>4){
						val[0]=fixColor$1(val[0]);
					}else {
						val[0]=[...val[0]];
					}
					if(val[1].length>4){
						val[1]=fixColor$1(val[1]);
					}else {
						val[1]=[...val[1]];
					}
					if(val[2].length>4){
						val[2]=fixColor$1(val[2]);
					}else {
						val[2]=[...val[2]];
					}
					if(val[3].length>4){
						val[3]=fixColor$1(val[3]);
					}else {
						val[3]=[...val[3]];
					}
					valMap[pptBorderColorIdx]=val;
					val=`rgba(${val[0][0]},${val[0][1]},${val[0][2]}, ${val[0][3]>=0?val[0][3]:1}) rgba(${val[1][0]},${val[1][1]},${val[1][2]}, ${val[1][3]>=0?val[1][3]:1}) rgba(${val[2][0]},${val[2][1]},${val[2][2]}, ${val[2][3]>=0?val[2][3]:1}) rgba(${val[3][0]},${val[3][1]},${val[3][2]}, ${val[3][3]>=0?val[3][3]:1})`;
				}
			}else {
				valMap[pptBorderColorIdx]=val;
			}
			valMap[pptStyleObjIdx].borderColor=val;
		};
		let get_=function(valMap){
			return valMap[pptBorderColorIdx];
		};
		typeDef.definePpt("borderColor",get_,set_,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt borderStyle:
	{
		setBorderStyle=function(valMap,val){
			valMap[pptBorderStyleIdx]=val;
			function v2s(v){
				switch(v){
					case 0:
					case false:
						return "none";
					case 1:
					case undefined:
						return "solid";
					case 2:
						return "dashed";
					case 3:
						return "dotted";
				}
				return v;
			}
			if(Array.isArray(val)){
				val=`${v2s(val[0])} ${v2s(val[1])} ${v2s(val[2])} ${v2s(val[3])}`;
			}else {
				val=v2s(val);
			}
			valMap[pptStyleObjIdx].borderStyle=val;
		};
		getBorderStyle=function(valMap){
			return valMap[pptBorderStyleIdx];
		};
		typeDef.definePpt("borderStyle",getBorderStyle,setBorderStyle,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt shadow-related:
	{
		let pptWillApplyIdx=typeDef.allocPptIdx("willApplyShadow",0);
		applyShadow=function(valMap){
			function _apply(){
				let onOff,inset,x,y,blur,spread,color,code;
				let styleObj;
				styleObj=valMap[pptStyleObjIdx];
				valMap[pptWillApplyIdx]=0;
				onOff=valMap[pptShadowIdx];
				if(!onOff){
					styleObj.boxShadow="none";
					return;
				}
				inset=valMap[pptShadowInsetIdx];
				x=valMap[pptShadowXIdx];
				y=valMap[pptShadowYIdx];
				blur=valMap[pptShadowBlurIdx];
				spread=valMap[pptShadowSpreadIdx];
				color=valMap[pptShadowColorIdx];
				if(Array.isArray(color)){
					color=`rgba(${color[0]||0},${color[1]||0},${color[2]||0},${color[3]>=0?color[3]:1})`;
				}
				code=`${x}px ${y}px ${blur}px ${spread}px ${color}`;
				if(inset){
					code="inset "+code;
				}
				styleObj.boxShadow=code;
			}
			if(valMap[pptWillApplyIdx]){
				return;
			}
			valMap[pptWillApplyIdx]=1;
			callAfter$1(_apply,0,valMap);
		};
		
		//ppt shadow:
		setShadow=function(valMap,val){
			val=!!val;
			valMap[pptShadowIdx]=val;
			applyShadow(valMap);
		};
		getShadow=function(valMap){
			return valMap[pptShadowIdx];
		};
		typeDef.definePpt("shadow",getShadow,setShadow,true);
		
		//ppt shadowX:
		setShadowX=function(valMap,val){
			valMap[pptShadowXIdx]=val;
			applyShadow(valMap);
		};
		getShadowX=function(valMap){
			return valMap[pptShadowXIdx];
		};
		typeDef.definePpt("shadowX",getShadowX,setShadowX,true);
		
		//ppt shadowY:
		setShadowY=function(valMap,val){
			valMap[pptShadowYIdx]=val;
			applyShadow(valMap);
		};
		getShadowY=function(valMap){
			return valMap[pptShadowYIdx];
		};
		typeDef.definePpt("shadowY",getShadowY,setShadowY,true);
		
		//ppt shadowBlur:
		setShadowBlur=function(valMap,val){
			valMap[pptShadowBlurIdx]=val;
			applyShadow(valMap);
		};
		getShadowBlur=function(valMap){
			return valMap[pptShadowBlurIdx];
		};
		typeDef.definePpt("shadowBlur",getShadowBlur,setShadowBlur,true);
		
		//ppt shadowSpread:
		setShadowSpread=function(valMap,val){
			valMap[pptShadowSpreadIdx]=val;
			applyShadow(valMap);
		};
		getShadowSpread=function(valMap){
			return valMap[pptShadowSpreadIdx];
		};
		typeDef.definePpt("shadowSpread",getShadowSpread,setShadowSpread,true);
		
		//ppt shadowColor:
		setShadowColor=function(valMap,val){
			valMap[pptShadowColorIdx]=val;
			applyShadow(valMap);
		};
		getShadowColor=function(valMap){
			return valMap[pptShadowColorIdx];
		};
		typeDef.definePpt("shadowColor",getShadowColor,setShadowColor,true);
		
		//ppt shadowSpread:
		setShadowInset=function(valMap,val){
			valMap[pptShadowInsetIdx]=val;
			applyShadow(valMap);
		};
		getShadowInset=function(valMap){
			return valMap[pptShadowInsetIdx];
		};
		typeDef.definePpt("shadowInset",getShadowInset,setShadowInset,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt maskImage
	{
		setMaskImage=function(valMap,val){
			let styleObj;
			styleObj=valMap[pptStyleObjIdx];
			valMap[pptMaskImageIdx]=val;
			if(val){
				styleObj.maskImage=`url(${val})`;
				styleObj.webkitMaskImage=`url(${val})`;
				styleObj.webkitMaskSize = "100% 100%";
			}else {
				styleObj.maskImage="";
				styleObj.webkitMaskImage="";
			}
		};
		getMaskImage=function(valMap){
			return valMap[pptMaskImageIdx];
		};
		typeDef.definePpt("maskImage",getMaskImage,setMaskImage,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt clientWidth, clientHeight:
	{
		let pptWIdx=typeDef.getPptIdx("w");
		let pptHIdx=typeDef.getPptIdx("h");
		//------------------------------------------------------------------------
		let getClientW=function(valMap){
			let w;
			let webObj,borderSize;
			webObj=valMap[pptWebObjIdx];
			if(webObj.offsetParent){
				return webObj.clientWidth;
			}
			w=valMap[pptWIdx];
			borderSize=valMap[pptBorderIdx];
			if(borderSize>=0 || borderSize<0){
				w-=borderSize*2;
			}else if(Array.isArray(borderSize)){
				w-=(borderSize[3]||0)+(borderSize[1]||0);
			}
			return w>=0?w:0;
		};
		funcGetMap.set("clientW",getClientW);
		funcGetMap.set("clientWidth",getClientW);
		
		//------------------------------------------------------------------------
		let getClientH=function(valMap){
			let h;
			let webObj,borderSize;
			webObj=valMap[pptWebObjIdx];
			if(webObj.offsetParent){
				return webObj.clientHeight;
			}
			h=valMap[pptHIdx];
			borderSize=valMap[pptBorderIdx];
			if(borderSize>=0 || borderSize<0){
				h-=borderSize*2;
			}else if(Array.isArray(borderSize)){
				h-=(borderSize[0]||0)+(borderSize[2]||0);
			}
			return h>=0?h:0;
		};
		funcGetMap.set("clientH",getClientH);
		funcGetMap.set("clientHeight",getClientH);
	}
	
}
VFACTObj.setupBox=setupBox;

//****************************************************************************
//:Text properties:
//****************************************************************************
function setupText(typeDef){
	//text, color, align, wrap, text-shadow, etc...
	let funcGetMap=typeDef.getMap;
	let funcSetMap=typeDef.setMap;
	
	let pptTextDivIdx=typeDef.allocPptIdx("textDiv",null);
	
	let pptTextIdx=typeDef.allocPptIdx("text","");
	let pptColorIdx=typeDef.allocPptIdx("color",[0,0,0,1]);
	let pptAlignXIdx=typeDef.allocPptIdx("alignX");
	let pptAlignYIdx=typeDef.allocPptIdx("alignY");
	let pptWrapIdx=typeDef.allocPptIdx("wrap",false);
	let pptEllipsisIdx=typeDef.allocPptIdx("ellipsis",false);
	let pptFontIdx=typeDef.allocPptIdx("font");
	let pptFontSizeIdx=typeDef.allocPptIdx("fontSize");
	let pptWeightIdx=typeDef.allocPptIdx("weight");
	let pptSelectIdx=typeDef.allocPptIdx("selectable",false);
	let pptShadowIdx=typeDef.allocPptIdx("textShadow",false);
	let pptShadowXIdx=typeDef.allocPptIdx("textShadowX",1);
	let pptShadowYIdx=typeDef.allocPptIdx("textShadowY",1);
	let pptShadowBlurIdx=typeDef.allocPptIdx("textShadowBlur",2);
	let pptShadowColorIdx=typeDef.allocPptIdx("textShadowColor",[0,0,0,0.5]);
	let pptSizeCacheIdx=typeDef.allocPptIdx("sizeCache",null);
	
	let applyShadow;
	let setShadow,getShadow;
	let setShadowX,getShadowX;
	let setShadowY,getShadowY;
	let setShadowColor,getShadowColor;
	let setShadowBlur,getShadowBlur;
	
	Object.assign(typeDef.initStyle,{
		wordBreak:"keep-all",
		whiteSpace:"nowrap",
		userSelect:"none",
		webkitUserSelect:"none",
		webkitTouchCallout:"none",
	});
	
	typeDef.defaultPpts[pptDisplayCodeIdx]="flex";
	typeDef.createElement=function(def,pptList){
		let box,txtDiv;
		box=document.createElement("div");
		txtDiv=document.createElement("div");
		txtDiv.style.pointerEvents="none";
		box.appendChild(txtDiv);
		pptList[pptTextDivIdx]=txtDiv;
		return box;
	};
	
	//--------------------------------------------------------------------------
	//ppt text:
	{
		let _set=function(valMap,val){
			let txtDiv=valMap[pptTextDivIdx];
			valMap[pptTextIdx]=""+val;
			txtDiv.innerHTML=escapeHTML(""+val);
			valMap[pptSizeCacheIdx]=null;
		};
		let _get=function(valMap){
			return unescapeHTML(valMap[pptTextIdx]);
		};
		typeDef.definePpt("text",_get,_set,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt color:
	{
		let setColor=function(valMap,val){
			if(Array.isArray(val)){
				if(val.length>4){
					val=fixColor$1(val);
				}else {
					val=[...val];
				}
				valMap[pptColorIdx]=val;
				val=`rgba(${val[0]||0},${val[1]||0},${val[2]||0})`;
			}else {
				valMap[pptColorIdx]=val;
			}
			valMap[pptStyleObjIdx].color=val;
		};
		let getColor=function(valMap){
			return valMap[pptColorIdx];
		};
		typeDef.definePpt("color",getColor,setColor,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt font:
	{
		let setFont=function(valMap,val){
			valMap[pptFontIdx]=val;
			valMap[pptStyleObjIdx].fontFamily=val;
			valMap[pptSizeCacheIdx]=null;
		};
		let getFont=function(valMap){
			return valMap[pptFontIdx];
		};
		typeDef.definePpt("font",getFont,setFont,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt fontSize:
	{
		let setFontSize=function(valMap,val){
			valMap[pptFontSizeIdx]=val;
			if(val>0){
				val=val+"px";
			}
			valMap[pptStyleObjIdx].fontSize=val;
			valMap[pptSizeCacheIdx]=null;
		};
		let getFontSize=function(valMap){
			return valMap[pptFontSizeIdx];
		};
		typeDef.definePpt("fontSize",getFontSize,setFontSize,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt alignX:
	{
		let setVal=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptAlignXIdx]=val;
			switch(val){
				case 0:
				case "left":
				default:
					styleObj.textAlign="start";
					styleObj.justifyContent="flex-start";
					break;
				case 1:
				case "center":
					styleObj.textAlign="center";
					styleObj.justifyContent="center";
					break;
				case 2:
				case "right":
					styleObj.textAlign="end";
					styleObj.justifyContent="flex-end";
					break;
			}
		};
		let getVal=function(valMap){
			return valMap[pptAlignXIdx];
		};
		typeDef.definePpt("alignX",getVal,setVal,true);
		funcGetMap.set("alignH",funcGetMap.get("alignX"));
		funcSetMap.set("alignH",funcSetMap.get("alignX"));
	}
	
	//--------------------------------------------------------------------------
	//ppt alignY:
	{
		let setVal=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptAlignYIdx]=val;
			switch(val){
				case 0:
				case "top":
				default:
					styleObj.alignItems="start";
					break;
				case 1:
				case "center":
					styleObj.alignItems="center";
					break;
				case 2:
				case "bottom":
					styleObj.alignItems="end";
					break;
			}
		};
		let getVal=function(valMap){
			return valMap[pptAlignYIdx];
		};
		typeDef.definePpt("alignY",getVal,setVal,true);
		funcGetMap.set("alignV",funcGetMap.get("alignY"));
		funcSetMap.set("alignV",funcSetMap.get("alignY"));
	}
	
	//--------------------------------------------------------------------------
	//ppt autoW
	{
		let pptWIdx=typeDef.getPptIdx("w");
		let funcSetW=funcSetMap.get("w");
		let setVal=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			val=!!val;
			if(val){
				styleObj.width="";
			}else {
				funcSetW(valMap,valMap[pptWIdx]);
			}
		};
		let getVal=function(valMap){
			let styleObj=valMap[pptStyleObjIdx];
			let w=styleObj.width;
			return w==="" || w===undefined || w==="auto";
		};
		typeDef.definePpt("autoWidth",getVal,setVal,true);
		funcGetMap.set("autoW",funcGetMap.get("autoWidth"));
		funcSetMap.set("autoW",funcSetMap.get("autoWidth"));
	}
	
	//--------------------------------------------------------------------------
	//ppt autoH
	{
		let pptHIdx=typeDef.getPptIdx("h");
		let funcSetH=funcSetMap.get("h");
		let setVal=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			val=!!val;
			if(val){
				styleObj.height="";
			}else {
				funcSetH(valMap,valMap[pptHIdx]);
			}
		};
		let getVal=function(valMap){
			let styleObj=valMap[pptStyleObjIdx];
			let h=styleObj.height;
			return h==="" || h===undefined;
		};
		typeDef.definePpt("autoHeight",getVal,setVal,true);
		funcGetMap.set("autoH",funcGetMap.get("autoHeight"));
		funcSetMap.set("autoH",funcSetMap.get("autoHeight"));
	}

	//--------------------------------------------------------------------------
	//ppt fontWeight:
	{
		let setVal=function(valMap,val){
			valMap[pptWeightIdx]=val;
			valMap[pptStyleObjIdx].fontWeight=val;
			valMap[pptSizeCacheIdx]=null;
		};
		let getVal=function(valMap){
			return valMap[pptWeightIdx];
		};
		typeDef.definePpt("fontWeight",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt fontStyle:
	{
		let setVal=function(valMap,val){
			valMap[pptStyleObjIdx].fontStyle=val;
		};
		let getVal=function(valMap){
			return valMap[pptStyleObjIdx].fontStyle;
		};
		typeDef.definePpt("fontStyle",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt textDecoration:
	{
		let setVal=function(valMap,val){
			valMap[pptStyleObjIdx].textDecoration=val;
		};
		let getVal=function(valMap){
			return valMap[pptStyleObjIdx].textDecoration;
		};
		typeDef.definePpt("textDecoration",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt selectable:
	{
		let setVal=function(valMap,val){
			let styleObj=valMap[pptStyleObjIdx];
			valMap[pptSelectIdx]=val;
			styleObj.userSelect=val?"text":"none";
			styleObj.webkitUserSelect=val?"text":"none";
			styleObj.webkitTouchCallout=val?"text":"none";
		};
		let getVal=function(valMap){
			return valMap[pptSelectIdx];
		};
		typeDef.definePpt("selectable",getVal,setVal,true);
		typeDef.definePpt("select",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt wrap:
	{
		let setVal=function(valMap,val){
			let txtStyle;
			let styleObj=valMap[pptStyleObjIdx];
			txtStyle=valMap[pptTextDivIdx].style;
			valMap[pptWrapIdx]=!!val;
			if(val){
				valMap[pptEllipsisIdx]=false;
				styleObj.whiteSpace="";
				styleObj.wordBreak="break-word";
				txtStyle.textOverflow= "";
			}else {
				styleObj.whiteSpace="nowrap";
				styleObj.wordBreak="keep-all";
			}
			valMap[pptSizeCacheIdx]=null;
		};
		let getVal=function(valMap){
			return valMap[pptWrapIdx];
		};
		typeDef.definePpt("wrap",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt ellipsis:
	{
		let setVal=function(valMap,val){
			let txtStyle;
			let styleObj=valMap[pptStyleObjIdx];
			txtStyle=valMap[pptTextDivIdx].style;
			valMap[pptEllipsisIdx]=!!val;
			if(val){
				valMap[pptWrapIdx]=false;
				styleObj.whiteSpace="nowrap";
				styleObj.wordBreak="keep-all";
				txtStyle.minWidth="0px";
				txtStyle.overflow="hidden";
				txtStyle.textOverflow="ellipsis";
			}else {
				txtStyle.textOverflow= "";
				txtStyle.minWidth="";
				txtStyle.overflow="";
			}
			valMap[pptSizeCacheIdx]=null;
		};
		let getVal=function(valMap){
			return valMap[pptEllipsisIdx];
		};
		typeDef.definePpt("ellipsis",getVal,setVal,true);
	}
	
	//--------------------------------------------------------------------------
	//ppt shadow-related:
	{
		let willApply=0;
		applyShadow=function(valMap){
			let styleObj=valMap[pptStyleObjIdx];
			function _apply(){
				let onOff,x,y,blur,color,code;
				willApply=0;
				onOff=valMap[pptShadowIdx];
				if(!onOff){
					styleObj.textShadow="none";
					return;
				}
				x=valMap[pptShadowXIdx];
				y=valMap[pptShadowYIdx];
				blur=valMap[pptShadowBlurIdx];
				color=valMap[pptShadowColorIdx];
				if(Array.isArray(color)){
					color=`rgba(${color[0]||0},${color[1]||0},${color[2]||0},${color[3]>=0?color[3]:1})`;
				}
				code=`${color} ${x}px ${y}px ${blur}px`;
				styleObj.textShadow=code;
			}
			if(willApply){
				return;
			}
			willApply=1;
			callAfter$1(_apply,0,valMap);
		};
		
		//ppt shadow:
		setShadow=function(valMap,val){
			val=!!val;
			valMap[pptShadowIdx]=val;
			applyShadow(valMap);
		};
		getShadow=function(valMap){
			return valMap[pptShadowIdx];
		};
		typeDef.definePpt("textShadow",getShadow,setShadow,true);
		if(!typeDef.hasPpt("shadow")){
			typeDef.aliasPpt("textShadow","shadow");
		}
		
		//ppt shadowX:
		setShadowX=function(valMap,val){
			valMap[pptShadowXIdx]=val;
			applyShadow(valMap);
		};
		getShadowX=function(valMap){
			return valMap[pptShadowXIdx];
		};
		typeDef.definePpt("textShadowX",getShadowX,setShadowX,true);
		if(!typeDef.hasPpt("shadowX")){
			typeDef.aliasPpt("textShadowX","shadowX");
		}
		
		//ppt shadowY:
		setShadowY=function(valMap,val){
			valMap[pptShadowYIdx]=val;
			applyShadow(valMap);
		};
		getShadowY=function(valMap){
			return valMap[pptShadowYIdx];
		};
		typeDef.definePpt("textShadowY",getShadowY,setShadowY,true);
		if(!typeDef.hasPpt("shadowY")){
			typeDef.aliasPpt("textShadowY","shadowY");
		}
		
		//ppt shadowBlur:
		setShadowBlur=function(valMap,val){
			valMap[pptShadowBlurIdx]=val;
			applyShadow(valMap);
		};
		getShadowBlur=function(valMap){
			return valMap[pptShadowBlurIdx];
		};
		typeDef.definePpt("textShadowBlur",getShadowBlur,setShadowBlur,true);
		if(!typeDef.hasPpt("shadowBlur")){
			typeDef.aliasPpt("textShadowBlur","shadowBlur");
		}
		
		//ppt shadowColor:
		setShadowColor=function(valMap,val){
			valMap[pptShadowColorIdx]=val;
			applyShadow(valMap);
		};
		getShadowColor=function(valMap){
			return valMap[pptShadowColorIdx];
		};
		typeDef.definePpt("textShadowColor",getShadowColor,setShadowColor,true);
		if(!typeDef.hasPpt("shadowColor")){
			typeDef.aliasPpt("textShadowColor","shadowColor");
		}
	}
	
	//--------------------------------------------------------------------------
	//ppt textW,textH
	{
		let getTextW=function(valMap){
			let webObj,w,h;
			let txtDiv;
			let cachedSize;
			cachedSize=valMap[pptSizeCacheIdx];
			if(cachedSize){
				return cachedSize[0];
			}
			webObj=valMap[pptWebObjIdx];
			txtDiv = valMap[pptTextDivIdx];
			if(webObj.offsetParent) {
				w = txtDiv.scrollWidth;
				h = txtDiv.scrollHeight;
				valMap[pptSizeCacheIdx]=[w,h];
				return w>=0?w:0;
			}
			cachedSize=valMap[pptSizeCacheIdx]=getTextSize(valMap[pptTextIdx],txtDiv);
			return cachedSize[0];
		};
		funcGetMap.set("textW",getTextW);
		funcGetMap.set("textWidth",getTextW);
		
		let getTextH=function(valMap){
			let webObj,w,h;
			let txtDiv;
			let cachedSize;
			cachedSize=valMap[pptSizeCacheIdx];
			if(cachedSize){
				return cachedSize[0];
			}
			webObj=valMap[pptWebObjIdx];
			txtDiv = valMap[pptTextDivIdx];
			if(webObj.offsetParent) {
				w = txtDiv.scrollWidth;
				h = txtDiv.scrollHeight;
				valMap[pptSizeCacheIdx]=[w,h];
				return h>=0?h:0;
			}
			cachedSize=valMap[pptSizeCacheIdx]=getTextSize(valMap[pptTextIdx],txtDiv);
			return cachedSize[1];
		};
		funcGetMap.set("textH",getTextH);
		funcGetMap.set("textHeight",getTextH);
	}
	
	//--------------------------------------------------------------------------
	//isEllipsised()
	typeDef.defineFunction("isEllipsised",function(){
		let valMap=this;
		let txtDiv;
		if(valMap[pptEllipsisIdx]) {
			txtDiv = valMap[pptTextDivIdx];
			return txtDiv.scrollWidth>txtDiv.offsetWidth;
		}
		return false;
	});
}
VFACTObj.setupText=setupText;

//****************************************************************************
//:Image properties:
//****************************************************************************
function setupImage(typeDef,pathFix){
	let getMap,setMap;
	getMap=typeDef.getMap;
	setMap=typeDef.setMap;
	
	let pptImageIdx=typeDef.allocPptIdx("imageReady",false);
	let pptImageObjIdx=typeDef.allocPptIdx("imageObj",false);
	let pptImageReadyIdx=typeDef.allocPptIdx("image","");
	let pptImageWIdx=typeDef.defineIdxOnlyPpt("imageW",false);
	let pptImageHIdx=typeDef.defineIdxOnlyPpt("imageH",false);
	let pptAutoSizeIdx=typeDef.allocPptIdx("autoSize",false);
	let pptFitSizeIdx=typeDef.allocPptIdx("fitSize",false);
	let pptAlignXIdx=typeDef.allocPptIdx("alignX",1);
	let pptAlignYIdx=typeDef.allocPptIdx("alignY",1);
	let pptRepeatIdx=typeDef.allocPptIdx("repeat",0);
	let pptImageOffsetIdx=typeDef.allocPptIdx("imageOffset",0);
	let pptImageScaleXIdx=typeDef.allocPptIdx("imageScaleX",1);
	let pptImageScaleYIdx=typeDef.allocPptIdx("imageScaleY",1);
	//ppt for 3x3
	let pptImage3x3Idx=typeDef.allocPptIdx("image3x3",null);
	let pptImage3x3WidthIdx=typeDef.allocPptIdx("image3x3Width",null);
	
	let _setW=setMap.get("w");
	let _setH=setMap.get("h");
	
	let applyImagePos;
	let applyImageSize;
	let applyBorderImage;
	
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(pxy,def,webObj,styleObj,valMap){
		let imageObj;
		if(oldPrefix){
			def=oldPrefix.call(typeDef,pxy,def,webObj,styleObj,valMap);
		}
		imageObj=valMap[pptImageObjIdx]=new Image();
		imageObj.crossOrigin="anonymous";
		imageObj.onload=function(){
			let img3x3,img3x3Width;
			styleObj=valMap[pptStyleObjIdx];
			if(!styleObj){
				return;
			}
			valMap[pptImageReadyIdx]=1;
			valMap[pptImageWIdx]=imageObj.width;
			valMap[pptImageHIdx]=imageObj.height;
			img3x3=valMap[pptImage3x3Idx];
			img3x3Width=valMap[pptImage3x3WidthIdx]||img3x3;
			if(img3x3){
				styleObj.backgroundImage="";
				styleObj.borderImageSource="url(" + imageObj.src + ")";
				styleObj.borderImageSlice=img3x3[0]+" "+img3x3[1]+" "+img3x3[2]+" "+img3x3[3]+" fill";
				styleObj.borderImageWidth=img3x3Width[0]+"px "+img3x3Width[1]+"px "+img3x3Width[2]+"px "+img3x3Width[3]+"px";
				styleObj.borderImageRepeat="stretch";
			}else {
				styleObj.borderImageSource="";
				styleObj.backgroundImage = "url(" + imageObj.src + ")";
				applyImageSize(valMap);
			}
			if(pxy.OnLoad){
				pxy.OnLoad();
			}
		};
		imageObj.onerror=function(){
			valMap[pptImageReadyIdx]=0;
			valMap[pptImageWIdx]=0;
			valMap[pptImageHIdx]=0;
			styleObj.borderImageSource="";
			styleObj.backgroundImage="";
			if(pxy.OnError){
				pxy.OnError();
			}
		};
		return def;
	};
	
	//------------------------------------------------------------------------
	applyImageSize=function(valMap){
		let imgScaleX,imgScaleY,fitSize;
		let styleObj=valMap[pptStyleObjIdx];
		imgScaleX=valMap[pptImageScaleXIdx];
		imgScaleY=valMap[pptImageScaleYIdx];
		fitSize=valMap[pptFitSizeIdx];
		switch(fitSize){
			case true:
			case 1:
				valMap[pptAutoSizeIdx]=false;
				styleObj.backgroundSize=`${100*imgScaleX}% ${100*imgScaleY}%`;
				return;
			case "contain":
			case "cover":
				styleObj.backgroundSize=fitSize;
				return;
			default:
				if(valMap[pptImageReadyIdx]){
					styleObj.backgroundSize=`${valMap[pptImageWIdx]*imgScaleX}px ${valMap[pptImageWIdx]*imgScaleY}px`;
				}
				return;
		}
	};

	//------------------------------------------------------------------------
	applyBorderImage=function(valMap){
		let styleObj=valMap[pptStyleObjIdx];
		if(!styleObj){
			return;
		}
		let imageObj=valMap[pptImageObjIdx];
		if(imageObj && imageObj.width>0){
			let img3x3=valMap[pptImage3x3Idx];
			if(img3x3){
				let img3x3Width=valMap[pptImage3x3WidthIdx]||img3x3;
				styleObj.backgroundImage="";
				styleObj.borderImageSource="url(" + imageObj.src + ")";
				styleObj.borderImageSlice=img3x3[0]+" "+img3x3[1]+" "+img3x3[2]+" "+img3x3[3]+" fill";
				styleObj.borderImageWidth=img3x3Width[0]+"px "+img3x3Width[1]+"px "+img3x3Width[2]+"px "+img3x3Width[3]+"px";
			}else {
				styleObj.borderImageSource="";
				styleObj.backgroundImage = "url(" + imageObj.src + ")";
				applyImageSize(valMap);
			}
		}
	};
	
	applyImagePos=function(valMap){
		let posText,alignX,alignY,pos,posX,posY;
		let styleObj=valMap[pptStyleObjIdx];
		alignX=valMap[pptAlignXIdx];
		alignY=valMap[pptAlignYIdx];
		pos=valMap[pptImageOffsetIdx];
		switch(alignX){
			case 0:case 1:case 2:
				break;
			default:
				alignX=1;
				break;
			case "left":
				alignX=0;
				break;
			case "center":
				alignX=1;
				break;
			case "right":
				alignX=2;
				break;
		}
		switch(alignY){
			case 0:case 1:case 2:
				break;
			default:
				alignY=1;
				break;
			case "top":
				alignY=0;
				break;
			case "center":
				alignY=1;
				break;
			case "bottom":
				alignY=2;
				break;
		}
		if(pos>=0||pos<0){
			posX=posY=pos;
		}else if(Array.isArray(pos)){
			posX=pos[0];
			posY=pos[1];
		}else {
			posX=0;posY=0;
		}
		posText=(alignX===0?"left ":(alignX===2?"right ":"center "));
		if(alignX!==1) {
			posText += "" + posX + "px ";
		}
		posText+=(alignY===0?"top ":(alignY===2?"bottom ":"center "));
		if(alignY!==1) {
			posText += "" + posY + "px ";
		}
		styleObj.backgroundPosition=posText;
	};
	
	//************************************************************************
	//define ppts
	//************************************************************************
	{
		//--------------------------------------------------------------------
		//ppt autoSize
		{
			let _set=function(valMap,val){
				val=!!val;
				valMap[pptAutoSizeIdx]=val;
				if(val){
					valMap[pptFitSizeIdx]=false;
					if(valMap[pptImageReadyIdx]){
						_setW(valMap[pptImageWIdx]);
						_setH(valMap[pptImageHIdx]);
					}
				}
			};
			let _get=function(valMap){
				return valMap[pptAutoSizeIdx];
			};
			typeDef.definePpt("autoSize",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt fitSize
		{
			let _set=function(valMap,val){
				//val=!!val;
				valMap[pptFitSizeIdx]=val;
				applyImageSize(valMap);
			};
			let _get=function(valMap){
				return valMap[pptFitSizeIdx];
			};
			typeDef.definePpt("fitSize",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt alignX
		{
			let _set=function(valMap,val){
				valMap[pptAlignXIdx]=val;
				applyImagePos(valMap);
			};
			let _get=function(valMap){
				return valMap[pptAlignXIdx];
			};
			typeDef.definePpt("alignX",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt alignY
		{
			let _set=function(valMap,val){
				valMap[pptAlignYIdx]=val;
				applyImagePos(valMap);
			};
			let _get=function(valMap){
				return valMap[pptAlignYIdx];
			};
			typeDef.definePpt("alignY",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt repeat
		{
			let _set=function(valMap,val){
				let repeatX,repeatY;
				let styleObj=valMap[pptStyleObjIdx];
				valMap[pptRepeatIdx]=val;
				if(typeof(val)==="string"){
					styleObj.backgroundRepeat=val;
					return;
				}else if(Array.isArray(val)){
					repeatX=!!val[0];
					repeatY=!!val[1];
				}else {
					val=!!val;
					repeatX=repeatY=val;
				}
				styleObj.backgroundRepeat=(repeatX?"repeat ":"no-repeat ")+(repeatY?"repeat":"no-repeat");
			};
			let _get=function(valMap){
				return valMap[pptRepeatIdx];
			};
			typeDef.definePpt("repeat",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt imageOffset
		{
			let _set=function(valMap,val){
				valMap[pptImageOffsetIdx]=val;
				applyImagePos(valMap);
			};
			let _get=function(valMap){
				return valMap[pptImageOffsetIdx];
			};
			typeDef.definePpt("imageOffset",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt imageScale
		{
			let _set=function(valMap,val){
				let scaleX,scaleY;
				if(Array.isArray(val)){
					scaleX=val[0];
					scaleY=val[1];
				}else {
					scaleX=scaleY=val;
				}
				valMap[pptImageScaleXIdx]=scaleX;
				valMap[pptImageScaleYIdx]=scaleY;
				applyImageSize(valMap);
			};
			let _get=function(valMap){
				return valMap[pptRepeatIdx];
			};
			typeDef.definePpt("imageScale",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt image
		{
			let _set=function(valMap,val){
				let imgObj,curURL;
				imgObj=valMap[pptImageObjIdx];
				if(pathFix){
					val=pathFix(val);
				}
				curURL=valMap[pptImageIdx];
				if(curURL!==val){
					valMap[pptImageIdx]=val;
					valMap[pptImageReadyIdx]=0;
					imgObj.src=val;
				}
			};
			let _get=function(valMap){
				return valMap[pptImageIdx];
			};
			typeDef.definePpt("image",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt imageW,imageH
		{
			let getImageW=function(valMap){
				return valMap[pptImageWIdx];
			};
			getMap.set("imgW",getImageW);
			getMap.set("imageW",getImageW);
			getMap.set("imageWidth",getImageW);

			let getImageH=function(valMap){
				return valMap[pptImageHIdx];
			};
			getMap.set("imgH",getImageH);
			getMap.set("imageH",getImageH);
			getMap.set("imageHeight",getImageH);
		}

		//--------------------------------------------------------------------
		//ppt image3x3
		{
			let _set=function(valMap,val){
				if(Array.isArray(val)){
					valMap[pptImage3x3Idx]=val;
				}else {
					valMap[pptImage3x3Idx]=null;
				}
				applyBorderImage(valMap);
			};
			let _get=function(valMap){
				return valMap[pptImage3x3Idx];
			};
			typeDef.definePpt("image3x3",_get,_set,true);
		}
		
		//--------------------------------------------------------------------
		//ppt image3x3Width
		{
			let _set=function(valMap,val){
				if(Array.isArray(val)){
					valMap[pptImage3x3WidthIdx]=val;
				}else {
					valMap[pptImage3x3WidthIdx]=null;
				}
				applyBorderImage(valMap);
			};
			let _get=function(valMap){
				return valMap[pptImage3x3WidthIdx];
			};
			typeDef.definePpt("image3x3Width",_get,_set,true);
		}
	}
}
VFACTObj.setupImage=setupImage;

//****************************************************************************
//:Button:
//****************************************************************************
function setupButton(typeDef){
	
	const STATE_UP=0;
	const STATE_DOWN=1;
	const STATE_OVER=2;
	const STATE_GRAY=3;
	
	let pptIsLabelIdx=typeDef.allocPptIdx("isLabel",false);
	let pptLabelTgtIdx=typeDef.allocPptIdx("labelTgt",false);
	typeDef.allocPptIdx("labelDiv",null);
	let pptStateIdx=typeDef.allocPptIdx("state",STATE_UP);
	let pptEnableIdx=typeDef.allocPptIdx("enable",true);
	let pptIsPenDownIdx=typeDef.defineIdxOnlyPpt("isPenDown",false,false);
	let pptIsPenInIdx=typeDef.defineIdxOnlyPpt("isPenIn",0,false);
	let pptDragIdx=typeDef.defineIdxOnlyPpt("drag",0,false);
	let pptInDragIdx=typeDef.defineIdxOnlyPpt("inDrag",0,false);
	let pptOnDragStartIdx=typeDef.defineIdxOnlyPptCall("OnDragStart",null,false);
	let pptOnDragIdx=typeDef.defineIdxOnlyPptCall("OnDrag",null,false);
	let pptOnDragEndIdx=typeDef.defineIdxOnlyPptCall("OnDragEnd",null,false);
	let pptOnButtonDownIdx=typeDef.defineIdxOnlyPptCall("OnButtonDown",null,false);
	let pptOnButtonUpIdx=typeDef.defineIdxOnlyPptCall("OnButtonUp",null,false);
	let pptOnMouseUpOutIdx=typeDef.defineIdxOnlyPptCall("OnMouseUpOut",null,false);
	let pptOnContextMenuIdx=typeDef.defineIdxOnlyPptCall("OnContextMenu",null,false);
	
	let pptOnClickIdx=typeDef.defineIdxOnlyPptCall("OnClick",null,false);
	
	let setState;
	
	let _OnMouseDown,_OnMouseEnter,_OnMouseLeave,_OnMouseUp,_OnMouseUpOut,_OnContextMenu;
	typeDef.allocPptIdx("OnMouseDown");
	let lastDownX,lastDownY;
	const MOVE_GAP=70;
	
	_OnMouseDown=function(valMap,evt){
		if(!valMap[pptEnableIdx]){
			return;
		}
		if(valMap[pptDragIdx]===2){
			valMap[pptIsPenDownIdx]=0;
			valMap[pptInDragIdx]=1;
			valMap[pptOnDragStartIdx] && valMap[pptOnDragStartIdx](evt);
			sysStartDrag(evt,{
				OnDrag:valMap[pptOnDragIdx],
				OnDone:(evt,dx,dy)=>{
					valMap[pptInDragIdx]=0;
					valMap[pptOnDragEndIdx] && valMap[pptOnDragEndIdx](evt,dx,dy);
				}
			});
			evt.stopPropagation();
		}else {
			let overcall;
			lastDownX=evt.x;
			lastDownY=evt.y;
			overcall=valMap[pptOnButtonDownIdx];
			if(overcall && overcall(1,evt)){
				return;
			}
			valMap[pptIsPenDownIdx]=1;
			setState(valMap,STATE_DOWN);
			sysAddOnMouseUp(valMap[pptOnMouseUpOutIdx]);
			evt.stopPropagation();
		}
	};
	
	_OnMouseEnter=function(valMap,evt){
		if(!valMap[pptEnableIdx]){
			return;
		}
		if(valMap[pptIsPenInIdx]){
			return;
		}
		valMap[pptIsPenInIdx]=1;
		if(valMap[pptIsPenDownIdx]){
			let overcall;
			overcall=valMap[pptOnButtonDownIdx];
			if(overcall){
				overcall(0,evt);
			}
			setState(valMap,STATE_DOWN);
			return;
		}
		setState(valMap,STATE_OVER);
	};
	
	_OnMouseLeave=function(valMap,evt){
		if(!valMap[pptEnableIdx]){
			return;
		}
		if(!valMap[pptIsPenInIdx]){
			return;
		}
		valMap[pptIsPenInIdx]=0;
		if(valMap[pptIsPenDownIdx]){
			//check if start drag:
			if(valMap[pptDragIdx]===1){
				valMap[pptIsPenDownIdx]=0;
				valMap[pptInDragIdx]=1;
				valMap[pptOnDragStartIdx] && valMap[pptOnDragStartIdx](evt);
				sysStartDrag(evt,{
					OnDrag:valMap[pptOnDragIdx],
					OnDone:(evt,dx,dy)=>{
						valMap[pptInDragIdx]=0;
						valMap[pptOnDragEndIdx] && valMap[pptOnDragEndIdx](evt);
					}
				});
				evt.stopPropagation();
				return;
			}
			let overcall;
			overcall=valMap[pptOnButtonUpIdx];
			if(overcall){
				overcall(0,evt);
			}
		}
		setState(valMap,STATE_UP);
	};
	
	_OnMouseUp=function(valMap,evt){
		let dx,dy;
		if(!valMap[pptEnableIdx]){
			return;
		}
		if(!valMap[pptIsPenDownIdx]){
			return;
		}
		dx=evt.x-lastDownX;
		dy=evt.y-lastDownY;
		dx=dx<0?-dx:dx;
		dy=dy<0?-dy:dy;
		if(dx+dy>MOVE_GAP){
			return;
		}
		/*if(evt.target!==valMap[pptWebObjIdx]){
			return;
		}*/
		evt.stopPropagation();
		evt.preventDefault();
		sysRemoveOnMouseUp(valMap[pptOnMouseUpOutIdx]);
		valMap[pptIsPenDownIdx]=0;
		let call,labelTgt;
		labelTgt=valMap[pptLabelTgtIdx];
		if(labelTgt){
			var newEvt;
			newEvt=new MouseEvent("click", {
				bubbles: true,cancelable: true,view: window
			});
			labelTgt.dispatchEvent(newEvt);
			return;
		}
		call=valMap[pptOnButtonUpIdx];
		if(call){
			if(call(1,evt)){
				setState(valMap,STATE_UP);
				return;
			}
		}
		call=valMap[pptOnClickIdx];
		if(call){
			let rst;
			vmcAddRefcount.call(valMap);
			rst=call(evt);
			if(valMap[pptEnableIdx]){
				if(rst===false){
					setState(valMap,STATE_OVER);
				}else {
					setState(valMap,STATE_UP);
					valMap[pptIsPenInIdx]=0;
				}
			}
			vmcRelease.call(valMap);
		}else {
			setState(valMap,STATE_UP);
			valMap[pptIsPenInIdx]=0;
		}
	};
	
	_OnMouseUpOut=function(valMap,evt){
		if(!valMap[pptEnableIdx]){
			return;
		}
		if(!valMap[pptIsPenDownIdx]){
			return;
		}
		valMap[pptIsPenDownIdx]=0;
		sysRemoveOnMouseUp(valMap[pptOnMouseUpOutIdx]);
		let call;
		call=valMap[pptOnButtonUpIdx];
		if(call){
			call(0,evt);
		}
		setState(valMap,STATE_UP);
	};

	_OnContextMenu=function(valMap,evt){
		let call=valMap[pptOnContextMenuIdx];
		if(!valMap[pptEnableIdx]){
			if(call){
				evt.preventDefault();
			}
			return;
		}
		if(call){
			call(evt);
			evt.preventDefault();
		}
	};
	
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(pxy,def,webObj,styleObj,valMap){
		if(oldPrefix){
			def=oldPrefix.call(typeDef,pxy,def,webObj,styleObj,valMap);
		}
		if(def.labelHtml){
			let div,labelTgt;
			//setup label-target:
			valMap[pptIsLabelIdx]=1;
			div=document.createElement('div');
			div.style.position="absolute";
			div.style.height="0px";
			div.style.opacity="0";
			div.style.overflow="hidden";
			div.innerHTML=def.labelHtml;
			labelTgt=div.firstChild;
			if(labelTgt){
				labelTgt.onchange=def.OnLabelAction||def.OnLableAction;
				valMap[pptLabelTgtIdx]=labelTgt;
			}
			webObj.appendChild(div);
			delete def.labelHtml;
		}
		//Install event handlers:
		webObj.addEventListener("contextmenu",(evt)=>{_OnContextMenu(valMap,evt);},false);
		webObj.addEventListener("mousedown",(evt)=>{_OnMouseDown(valMap,evt);},false);
		webObj.addEventListener("mouseenter",(evt)=>{_OnMouseEnter(valMap,evt);},false);
		webObj.addEventListener("mouseleave",(evt)=>{_OnMouseLeave(valMap,evt);},false);
		webObj.addEventListener("mouseup",(evt)=>{_OnMouseUp(valMap,evt);},true);
		webObj.addEventListener("touchstart",(evt)=>{_OnMouseDown(valMap,evt);},false);
		webObj.addEventListener("touchend",(evt)=>{_OnMouseUp(valMap,evt);},true);
		valMap[pptOnMouseUpOutIdx]=(evt)=>{_OnMouseUpOut(valMap,evt);};
		return def;
	};
	let oldPost=typeDef.postCreate;
	typeDef.postCreate=function(pxy,def,webObj,styleObj,pptList){
		let state;
		if(oldPost){
			oldPost.call(typeDef,pxy,def,webObj,styleObj,pptList);
		}
		state=pptList[pptStateIdx];
		pptList[pptStateIdx]=null;
		setState(pptList,state);
	};
	
	//------------------------------------------------------------------------
	//ppt state:
	{
		let _set;
		_set=setState=function(valMap,val){
			let oldVal,faceCode;
			oldVal=valMap[pptStateIdx];
			if(oldVal===val){
				return;
			}
			switch(val){
				default:
				case STATE_UP:
					faceCode="up";
					break;
				case STATE_OVER:
					faceCode="over";
					break;
				case STATE_DOWN:
					faceCode="down";
					break;
				case STATE_GRAY:
					faceCode="gray";
					break;
			}
			valMap[pptStateIdx]=val;
			valMap[pptProxyIdx].showFace(faceCode);
		};
		let _get=function(valMap){
			return valMap[pptStateIdx];
		};
		typeDef.definePpt("state",_get,_set,false);
	}
	
	//------------------------------------------------------------------------
	//ppt enable:
	{
		let _set=function(valMap,val){
			let oldVal;
			oldVal=valMap[pptEnableIdx];
			val=!!val;
			valMap[pptEnableIdx]=val;
			if(val && !oldVal){
				setState(valMap,STATE_UP);
			}else if(!val && oldVal){
				setState(valMap,STATE_GRAY);
			}
		};
		let _get=function(valMap){
			return valMap[pptEnableIdx];
		};
		typeDef.definePpt("enable",_get,_set,true);
	}
}
VFACTObj.setupButton=setupButton;

//****************************************************************************
//:Edit:
//****************************************************************************
function setupEditCore(typeDef,isMemo){
	let getMap;
	
	getMap=typeDef.getMap;

	let pptColorIdx=typeDef.allocPptIdx("color",[0,0,0,1]);
	let pptFontIdx=typeDef.allocPptIdx("font","");
	let pptFontSizeIdx=typeDef.allocPptIdx("fontSize",16);
	let pptWeightIdx=typeDef.allocPptIdx("weight","");

	let pptAutoSelectIdx=typeDef.defineIdxOnlyPpt("autoSelect",true);
	
	let pptOnInputIdx=typeDef.defineIdxOnlyPptCall("OnInput",null,false);
	let pptOnChangeIdx=typeDef.defineIdxOnlyPptCall("OnChange",null,false);
	let pptOnUpdateIdx=typeDef.defineIdxOnlyPptCall("OnUpdate",null,false);
	let pptOnFocusIdx=typeDef.defineIdxOnlyPptCall("OnFocus",null,false);
	let pptOnBlurIdx=typeDef.defineIdxOnlyPptCall("OnBlur",null,false);
	let pptOnCancelIdx=typeDef.defineIdxOnlyPptCall("OnCancel",null,false);
	let pptOnKeyDownIdx=typeDef.defineIdxOnlyPptCall("OnKeyDown",null,false);
	let pptOnKeyUpIdx=typeDef.defineIdxOnlyPptCall("OnKeyUp",null,false);
	let pptOnPressKeyUpIdx=typeDef.defineIdxOnlyPptCall("OnPressKeyUp",null,false);
	let pptOnPressKeyDownIdx=typeDef.defineIdxOnlyPptCall("OnPressKeyDown",null,false);
	let pptOnNxtEditIdx=typeDef.defineIdxOnlyPptCall("OnNextEdit",null,false);
	let pptOnPreEditIdx=typeDef.defineIdxOnlyPptCall("OnPreviousEdit",null,false);

	let selectAll;
	
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(pxy,def,webObj,styleObj,valMap){
		let enterKeyTime=0;
		if(oldPrefix){
			def=oldPrefix.call(typeDef,pxy,def,webObj,styleObj,valMap);
		}
		webObj.setAttribute('autocomplete', 'off');
		//init event handlers:
		webObj.onfocus=function(evt){
			let call,autoSelect;
			autoSelect=valMap[pptAutoSelectIdx];
			if(autoSelect){
				selectAll.call(valMap);
			}
			call=valMap[pptOnFocusIdx];
			call && call(evt);
		};
		webObj.onblur=function(evt){
			let call;
			call=valMap[pptOnBlurIdx];
			call && call(evt);
		};
		webObj.oninput=function(evt){
			let call;
			call=valMap[pptOnInputIdx];
			call && call(evt);
		};
		webObj.onchange=function(e){
			let time;
			let call;
			call=valMap[pptOnChangeIdx];
			if(call){
				time=Date.now()-enterKeyTime;
				if(time<30) {
					call(e);
				}
			}
		};
		if(isMemo){
			webObj.onkeydown=function(evt){
				let call;
				call=valMap[pptOnKeyDownIdx];
				if(call && call(evt)){
					evt.stopPropagation();
					evt.preventDefault();
					return;
				}
				if(evt.code==="Enter"){
					enterKeyTime=Date.now();
					if((!evt.isComposing) &&(!evt.shiftKey)){
						call=valMap[pptOnUpdateIdx];
						call && call(evt);
					}
				}else if(evt.code==="Escape"){
					call=valMap[pptOnCancelIdx];
					call && call(evt);
				}
			};
		}else {
			webObj.onkeydown=function(evt){
				let call;
				call=valMap[pptOnKeyDownIdx];
				if(call && call(evt)){
					evt.stopPropagation();
					evt.preventDefault();
					return;
				}
				if(evt.code==="Enter"){
					enterKeyTime=Date.now();
					if((!evt.isComposing)){
						call=valMap[pptOnUpdateIdx];
						call && call(evt);
					}
				}else if(evt.code==="Escape"){
					if((!evt.isComposing)){
						call=valMap[pptOnCancelIdx];
						call && call(evt);
					}
				}else if(evt.code==="ArrowUp"){
					call=valMap[pptOnPressKeyUpIdx];
					if(call && call(evt)){
						evt.stopPropagation();
						evt.preventDefault();
					}
				}else if(evt.code==="ArrowDown"){
					call=valMap[pptOnPressKeyDownIdx];
					if(call && call(evt)){
						evt.stopPropagation();
						evt.preventDefault();
					}
				}else if(evt.code==="Tab"){
					if(evt.shiftKey){
						call=valMap[pptOnPreEditIdx];
						if(call && call(evt)){
							evt.stopPropagation();
							evt.preventDefault();
						}
					}else {
						call=valMap[pptOnNxtEditIdx];
						if(call && call(evt)){
							evt.stopPropagation();
							evt.preventDefault();
						}
					}
				}
			};
		}
		webObj.onkeyup=function(evt){
			let call;
			call=valMap[pptOnKeyUpIdx];
			if(call && call(evt)){
				evt.stopPropagation();
				evt.preventDefault();
			}
		};
		return def;
	};
	//------------------------------------------------------------------------
	//ppt color:
	{
		let setColor=function(valMap,val){
			if(Array.isArray(val)){
				if(val.length>4){
					val=fixColor$1(val);
				}else {
					val=[...val];
				}
				valMap[pptColorIdx]=val;
				val=`rgba(${val[0]||0},${val[1]||0},${val[2]||0})`;
			}else {
				valMap[pptColorIdx]=val;
			}
			valMap[pptStyleObjIdx].color=val;
		};
		let getColor=function(valMap){
			return valMap[pptColorIdx];
		};
		typeDef.definePpt("color",getColor,setColor,true);
	}
	
	//------------------------------------------------------------------------
	//ppt font:
	{
		let setFont=function(valMap,val){
			valMap[pptFontIdx]=val;
			valMap[pptStyleObjIdx].fontFamily=val;
		};
		let getFont=function(valMap){
			return valMap[pptFontIdx];
		};
		typeDef.definePpt("font",getFont,setFont,true);
	}
	
	//------------------------------------------------------------------------
	//ppt fontSize:
	{
		let setFontSize=function(valMap,val){
			valMap[pptFontIdx]=val;
			if(val>0){
				val=val+"px";
			}
			valMap[pptStyleObjIdx].fontSize=val;
		};
		let getFontSize=function(valMap){
			return valMap[pptFontSizeIdx];
		};
		typeDef.definePpt("fontSize",getFontSize,setFontSize,true);
	}
	
	//------------------------------------------------------------------------
	//ppt fontWeight:
	{
		let setVal=function(valMap,val){
			valMap[pptWeightIdx]=val;
			valMap[pptStyleObjIdx].fontWeight=val;
		};
		let getVal=function(valMap){
			return valMap[pptWeightIdx];
		};
		typeDef.definePpt("fontWeight",getVal,setVal,true);
	}
	
	//------------------------------------------------------------------------
	//ppt fontStyle:
	{
		let setVal=function(valMap,val){
			valMap[pptStyleObjIdx].fontStyle=val;
		};
		let getVal=function(valMap){
			return valMap[pptStyleObjIdx].fontStyle;
		};
		typeDef.definePpt("fontStyle",getVal,setVal,true);
	}
	
	//------------------------------------------------------------------------
	//ppt textDecoration:
	{
		let setVal=function(valMap,val){
			valMap[pptStyleObjIdx].textDecoration=val;
		};
		let getVal=function(valMap){
			return valMap[pptStyleObjIdx].textDecoration;
		};
		typeDef.definePpt("textDecoration",getVal,setVal,true);
	}
	
	//------------------------------------------------------------------------
	//focus
	{
		let callIdx=typeDef.allocPptIdx("focus()",null);
		let _focus=function(valMap){
			let call=valMap[callIdx];
			if(!call){
				call=valMap[callIdx]=()=>{
					let autoSelect;
					valMap[pptWebObjIdx].focus();
					autoSelect=valMap[pptAutoSelectIdx];
					if(autoSelect){
						selectAll.call(valMap);
					}
				};
			}
			return call;
		};
		getMap.set("focus",_focus);
		getMap.set("startEdit",_focus);
	}
	
	//------------------------------------------------------------------------
	//blur
	{
		let callIdx=typeDef.allocPptIdx("blur()",null);
		let _call=function(valMap){
			let call=valMap[callIdx];
			if(!call){
				call=valMap[callIdx]=()=>{
					valMap[pptWebObjIdx].blur();
				};
			}
			return call;
		};
		getMap.set("blur",_call);
		getMap.set("endEdit",_call);
	}
	
	//------------------------------------------------------------------------
	//selectAll
	{
		selectAll=function(){
			let valMap=this;
			let webObj=valMap[pptWebObjIdx];
			if(isMemo){
				let myDiv = webObj;
				let range = document.createRange();
				range.selectNodeContents(myDiv);
				if(webObj.innerText){
					let selection = window.getSelection();
					selection.removeAllRanges();
					selection.addRange(range);			
				}
			}else {
				try{
					if(webObj.setSelectionRange){
						webObj.setSelectionRange(0,webObj.value.length);
					}else {
						let myDiv = webObj;
						let range = document.createRange();
						range.selectNodeContents(myDiv);
						let selection = window.getSelection();
						selection.removeAllRanges();
						selection.addRange(range);			
					}
				}catch(err){
				}
			}
		};
		typeDef.defineFunction("selectAll",selectAll);
	}
}

function setupEdit(typeDef){
	
	typeDef.allocPptIdx("align",0);
	
	typeDef.createElement=function(def,pptMap){
		let obj;
		obj=document.createElement("input");
		obj.type=def.inputType||"text";
		return obj;
	};
	
	setupEditCore(typeDef,false);
	
	//------------------------------------------------------------------------
	//ppt inputType:
	{
		let setInputType=function(valMap,val){
			valMap[pptWebObjIdx].type = val;
		};
		let getInputType=function(valMap){
			return valMap[pptWebObjIdx].type;
		};
		typeDef.definePpt("inputType",getInputType,setInputType,true);
	}
	
	//------------------------------------------------------------------------
	//ppt pattern:
	{
		let setPattern=function(valMap,val){
			valMap[pptWebObjIdx].pattern = val;
		};
		let getPattern=function(valMap){
			return valMap[pptWebObjIdx].pattern;
		};
		typeDef.definePpt("pattern",getPattern,setPattern,true);
	}
	
	//------------------------------------------------------------------------
	//ppt text:
	{
		let setText=function(valMap,val){
			valMap[pptWebObjIdx].value = val;
		};
		let getText=function(valMap){
			return valMap[pptWebObjIdx].value;
		};
		typeDef.definePpt("text",getText,setText,true);
	}
	
	//------------------------------------------------------------------------
	//ppt placeholder:
	{
		let setPlaceHolder=function(valMap,val){
			valMap[pptWebObjIdx].placeholder = val;
		};
		let getPlaceHolder=function(valMap){
			return valMap[pptWebObjIdx].placeholder;
		};
		typeDef.definePpt("placeHolder",getPlaceHolder,setPlaceHolder,true);
	}

	//------------------------------------------------------------------------
	//ppt readOnly:
	{
		let setReadOnly=function(valMap,val){
			val=!!val;
			valMap[pptWebObjIdx].readOnly=val;
		};
		let getReadOnly=function(valMap){
			return !!(valMap[pptWebObjIdx].readOnly);
		};
		typeDef.definePpt("readOnly",getReadOnly,setReadOnly,true);
	}
	
	//------------------------------------------------------------------------
	//selectionStart
	{
		let getSelectionStart=function(valMap){
			return valMap[pptWebObjIdx].selectionStart;
		};
		let setSelectionStart=function(valMap,val){
			valMap[pptWebObjIdx].selectionStart=val;
		};
		typeDef.definePpt("selectionStart",getSelectionStart,setSelectionStart,true);
	}
	
	//------------------------------------------------------------------------
	//selectionEnd
	{
		let getSelectionEnd=function(valMap){
			return valMap[pptWebObjIdx].selectionEnd;
		};
		let setSelectionEnd=function(valMap,val){
			valMap[pptWebObjIdx].selectionEnd=val;
		};
		typeDef.definePpt("selectionEnd",getSelectionEnd,setSelectionEnd,true);
	}
	
	//------------------------------------------------------------------------
	//setSelectionRange
	{
		typeDef.defineFunction("setSelectionRange",function(p1,p2){
			let valMap=this;
			p1=p1||0;
			if(p2===undefined){
				p2=p1;
			}
			valMap[pptWebObjIdx].setSelectionRange(p1,p2);
		});
	}
}
VFACTObj.setupEdit=setupEdit;

function setupEditMemo(typeDef){

	
	typeDef.createElement=function(def,pptMap){
		let obj;
		obj=document.createElement("div");
		obj.contentEditable="true";
		obj.style.padding="5px";
		obj.style.overflow="auto";
		obj.style.cursor="text";
		return obj;
	};

	setupEditCore(typeDef,true);

	//------------------------------------------------------------------------
	//ppt text:
	{
		let setText=function(valMap,val){
			if(val){
				valMap[pptWebObjIdx].innerText = val;
			}else {
				valMap[pptWebObjIdx].innerHTML="";
			}
		};
		let getText=function(valMap){
			return valMap[pptWebObjIdx].innerText;
		};
		typeDef.definePpt("text",getText,setText,true);
	}

	//------------------------------------------------------------------------
	//ppt readOnly:
	let pptReadOnlyIdx=typeDef.allocPptIdx("readOnly",false);
	{
		let setReadOnly=function(valMap,val){
			valMap[pptReadOnlyIdx]=val;
			val=!!val;
			valMap[pptWebObjIdx].contentEditable=val?"false":"true";
		};
		let getReadOnly=function(valMap){
			return valMap[pptReadOnlyIdx];
		};
		typeDef.definePpt("readOnly",getReadOnly,setReadOnly,true);
	}
}VFACTObj.setupEditMemo=setupEditMemo;

//****************************************************************************
//:Docker:
//****************************************************************************
function setupDocker(typeDef){
	let getMap;
	getMap=typeDef.getMap;
	
	let pptUIListIdx=typeDef.allocPptIdx("uiList",null,false);
	let pptUIStackIdx=typeDef.allocPptIdx("uiStack",null,false);
	let pptCurUIIdx=typeDef.allocPptIdx("curUI",null,false);
	let pptCoverActionIdx=typeDef.defineIdxOnlyPpt("coverAction",1,false);
	
	let showUI;
	
	//--------------------------------------------------------------------
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(pxy,def,weObj,styleObj,valMap){
		if(oldPrefix){
			def=oldPrefix(pxy,def,weObj,styleObj,valMap);
		}
		valMap[pptUIStackIdx]=[];
		valMap[pptUIListIdx]=[];
		if(typeof(def.ui)==="object"){
			if(def.children){
				def.children.push(def.ui);
				def.ui=def.children.length-1;
			}else {
				def.children=[def.ui];
				def.ui=0;
			}
		}
		return def;
	};

	typeDef.OnFree=function(valMap){
		let subUIs,subUI;
		subUIs=valMap[pptUIListIdx];
		for(subUI of subUIs){
			subUI.release();
		}
	};
	
	//--------------------------------------------------------------------
	let oldPostCreate=typeDef.postCreate;
	typeDef.postCreate=function(pxy,def,webObj,styleObj,valMap){
		let subUIs,list,i,n,node,subUI,uiIdx,ui;
		if(oldPostCreate){
			oldPostCreate.call(typeDef,pxy,def,webObj,styleObj,valMap);
		}
		//covert all children to subUI:
		if(!def.$inEditor){
			subUIs=valMap[pptUIListIdx]=[];
			list=webObj.childNodes;
			n=list.length;
			for(i=0;i<n;i++){
				node=list[i];
				subUI=node.$_pxy;
				if(subUI){
					subUI.display=0;//Hide theUI
					subUI.hold();
					subUIs.push(subUI);
				}
			}
			uiIdx=def.ui;
			if(uiIdx>=0){
				ui=subUIs[uiIdx];
				if(ui){
					showUI.call(valMap,ui,{});
				}
			}else if(typeof(uiIdx)==="string"){
				for(ui of subUIs){
					if(ui.id===uiIdx){
						showUI.call(valMap,ui,{});
						break;
					}
				}
			}
		}
	};
	
	//--------------------------------------------------------------------
	//docker.showUI(ui,vo)
	{
		//----------------------------------------------------------------
		showUI=function(ui,vo){
			let valMap=this;
			let preUI,uiStack,idx,result,coverAction,owner;
			let pxy=valMap[pptProxyIdx];
			if(ui>=0){
				let subUIs=valMap[pptUIListIdx];
				ui=subUIs[ui];
			}
			if(!ui){
				return null;
			}
			uiStack=valMap[pptUIStackIdx];
			preUI=valMap[pptCurUIIdx];
			coverAction=valMap[pptCoverActionIdx];
			if(preUI===ui){
				//same UI:
				let showUIFunc;
				showUIFunc=ui.showUI;
				if(showUIFunc){
					result=showUIFunc.call(ui,vo);
					if(result instanceof Promise){
						result.then(()=>{
							let callback;
							callback=pxy.OnUIShowed;
							callback&&callback(ui);
						});
					}else {
						let callback;
						callback=pxy.OnUIShowed;
						callback&&callback(ui);
					}
				}else {
					let callback;
					callback=pxy.OnUIShowed;
					callback&&callback(ui);
				}
				return ui;
			}
			valMap[pptCurUIIdx]=ui;
			idx=uiStack.indexOf(ui);
			if(idx>=0){
				uiStack.splice(idx,1);
			}
			owner=ui.parent;
			if(!owner){
				pxy.appendChild(ui);
			}else if(owner!==pxy){
				throw Error("UI is not a child of docker.");
			}else {
				ui.hold();
				pxy.removeChild(ui);
				pxy.appendChild(ui);
				ui.release();
			}
			uiStack.push(ui);
			ui.display=1;
			if(preUI){
				preUI.uiEvent=0;
				pxy.OnCoverUI&&pxy.OnCoverUI(preUI,ui);
				if(preUI.coverUI) {
					preUI.coverUI();
				}
			}
			ui.uiEvent=0;
			result =ui.showUI?ui.showUI(vo,preUI):null;
			pxy.OnShowUI&&pxy.OnShowUI(ui,preUI);
			if(result instanceof Promise){
				result.then(()=>{
					ui.uiEvent=1;
					if(preUI) {
						preUI.OnUICovered&&preUI.OnUICovered();
						pxy.OnUICovered&&pxy.OnUICovered(preUI);
						if(coverAction===0) {
							preUI.display=0;
						}else if(coverAction===1) {
							idx=uiStack.indexOf(preUI);
							if(idx>=0){
								uiStack.splice(idx,1);
							}
							pxy.removeChild(preUI);
						}else if(coverAction===2){
							preUI.display=0;
						}
					}
					pxy.OnUIShowed&&pxy.OnUIShowed(ui);
				});
			}else {
				ui.uiEvent=1;
				if(preUI) {
					preUI.OnUICovered&&preUI.OnUICovered();
					pxy.OnUICovered&&pxy.OnUICovered(preUI);
					if(coverAction===0) {
						preUI.display=0;
					}else if(coverAction===1) {
						idx=uiStack.indexOf(preUI);
						if(idx>=0){
							uiStack.splice(idx,1);
						}
						pxy.removeChild(preUI);
					}else if(coverAction===2){
						preUI.display=0;
					}
				}
				pxy.OnUIShowed&&pxy.OnUIShowed(ui);
			}
			return ui;
		};
		typeDef.defineFunction("showUI",showUI);
	}
	
	//--------------------------------------------------------------------
	//docker.showNewUI(uiDef,vo)
	{
		typeDef.defineFunction("showNewUI",function(uiDef,vo){
			let valMap=this;
			let ui;
			let pxy=valMap[pptProxyIdx];
			ui=pxy.appendNewChild(uiDef);
			if(!ui){
				return null;
			}
			let subUIs=valMap[pptUIListIdx];
			subUIs.push(ui);
			return showUI.call(valMap,ui,vo);
		});
	}
	
	//--------------------------------------------------------------------
	//docker.dismissUI(ui)
	{
		typeDef.defineFunction("dismissUI",async function(ui,remove){
			let valMap=this;
			let uiStack,idx,topUI,uncover;
			let pxy=valMap[pptProxyIdx];
			uncover=false;
			uiStack=valMap[pptUIStackIdx];
			topUI=uiStack[uiStack.length-1];
			if(!ui){
				ui=topUI;
				if(!ui){
					return;
				}
			}
			idx=uiStack.indexOf(ui);
			if(idx>=0){
				uiStack.splice(idx,1);
			}
			if(ui===topUI){
				topUI=uiStack[uiStack.length-1];
				if(topUI){
					topUI.display=1;
					topUI.uiEvent=1;
					uncover=true;
				}
				valMap[pptCurUIIdx]=topUI;
			}
			//call ui's dissmis or animate a bit?
			if(uncover && topUI){
				topUI.OnUncover&&topUI.OnUncover();
			}
			if(ui.OnDismiss){
				await ui.OnDismiss();
			}
			if(uncover && topUI){
				topUI.OnUncovered&&topUI.OnUncovered();
			}
			
			if(remove){
				pxy.removeChild(ui);
			}else {
				ui.uiEvent=0;
				ui.display=0;
			}
		});
	}
	
	//--------------------------------------------------------------------
	//ppt uiStack:
	{
		let _get=function(valMap){
			return valMap[pptUIStackIdx];
		};
		getMap.set("uiStack",_get);
	}

	//--------------------------------------------------------------------
	//ppt uiList:
	{
		let _get=function(valMap){
			return valMap[pptUIListIdx];
		};
		getMap.set("uiList",_get);
	}

	//--------------------------------------------------------------------
	//ppt curUI:
	{
		let _get=function(valMap){
			return valMap[pptCurUIIdx];
		};
		getMap.set("curUI",_get);
	}
}
VFACTObj.setupDocker=setupDocker;

//****************************************************************************
//:Drag and drop:
//****************************************************************************
{
	//------------------------------------------------------------------------
	VFACT.applyDrag=function(pxy,vo){
		let valMap;
		let webObj;
		valMap=pxy.$_pptMap;
		webObj=valMap[pptWebObjIdx];
		if(!vo){
			vo=webObj.$_dragVO;
			if(!vo){
				return;
			}
			if(vo.OnDragStart) {
				webObj.removeEventListener(vo.OnDragStart);
			}
			if(vo.OnDrag) {
				webObj.removeEventListener(vo.OnDrag);
			}
			if(vo.OnDragEnd) {
				webObj.removeEventListener(vo.OnDrag);
			}
			webObj.draggable="false";
			return;
		}
		vo={...vo};
		webObj.draggable="true";
		webObj.$_dragVO=vo;
		if(vo.OnDragStart){
			vo.OnDragStart=vo.OnDragStart.bind(pxy);
			webObj.addEventListener("dragstart",vo.OnDragStart);
		}
		if(vo.OnDrag){
			vo.OnDrag=vo.OnDrag.bind(pxy);
			webObj.addEventListener("drag",vo.OnDrag);
		}
		if(vo.OnDragEnd){
			vo.OnDragEnd=vo.OnDragEnd.bind(pxy);
			webObj.addEventListener("dragend",vo.OnDragEnd);
		}
	};
	
	//------------------------------------------------------------------------
	VFACT.applyDrop=function(pxy,vo){
		let valMap;
		let webObj;
		valMap=pxy.$_pptMap;
		webObj=valMap[pptWebObjIdx];
		if(!vo){
			vo=webObj.$_dropVO;
			if(!vo){
				return;
			}
			if(vo.OnDragEnter){
				webObj.removeEventListener("dragenter",vo.OnDragEnter);
			}
			if(vo.OnDragOver){
				webObj.removeEventListener("dragover",vo.OnDragOver);
			}
			if(vo.OnDragLeave){
				webObj.removeEventListener("dragleave",vo.OnDragLeave);
			}
			if(vo.OnDrop){
				webObj.removeEventListener("drop",vo.OnDrop);
			}
		}
		vo={...vo};
		if(vo.OnDragEnter){
			vo.OnDragEnter=vo.OnDragEnter.bind(pxy);
			webObj.addEventListener("dragenter",vo.OnDragEnter);
		}
		if(vo.OnDragOver){
			vo.OnDragOver=vo.OnDragOver.bind(pxy);
			webObj.addEventListener("dragover",vo.OnDragOver);
		}
		if(vo.OnDragLeave){
			vo.OnDragLeave=vo.OnDragLeave.bind(pxy);
			webObj.addEventListener("dragleave",vo.OnDragLeave);
		}
		if(vo.OnDrop){
			vo.OnDrop=vo.OnDrop.bind(pxy);
			webObj.addEventListener("drop",vo.OnDrop);
		}
	};
	
	//------------------------------------------------------------------------
	VFACT.applyMoveDrag=function(pxy,tgtPxy,capture=false,fx=1,fy=1){
		let valMap;
		let webObj,startX,startY,orgX,orgY,gap=0;
		let OnStart,OnMove,OnEnd,OnMoved;
		let dragging=false;
		let meta={
			setTarget(tgt){
				tgtPxy=tgt;
			},
			setCallbacks(start,move,end,moved){
				OnStart=start;
				OnMove=move;
				OnEnd=end;
				OnMoved=moved;
			},
			setGap(newGap){
				gap=newGap;
			},
			setScale(sx,sy){
				fx=sx;fy=sy;
			}
		};

		function move(evt){
			let dx,dy;
			dx=evt.x-startX;
			dy=evt.y-startY;
			dx=dx*fx;
			dy=dy*fy;
			if(dragging){
				if(OnMove){
					OnMove(evt,tgtPxy,dx,dy,pxy);
				}else if(tgtPxy){
					tgtPxy.x=orgX+dx;
					tgtPxy.y=orgY+dy;
					if(!capture){
						evt.preventDefault();
						evt.stopPropagation();
					}
					if(OnMoved){
						OnMoved(evt,tgtPxy,pxy);
					}
				}
			}else {
				dx=dx<0?-dx:dx;
				dy=dy<0?-dy:dy;
				if(dx+dy>=gap){
					dragging=true;
					OnStart && OnStart(evt,tgtPxy,pxy);
				}
			}
		}
		function up(evt){
			if(dragging){
				evt.preventDefault();
				evt.stopPropagation();
				OnEnd && OnEnd(evt,tgtPxy,pxy);
			}
			dragging=false;
			document.body.removeEventListener("mousemove",move,true);
			document.body.removeEventListener("touchmove",move,true);
			document.body.removeEventListener("touchend",up,true);
			document.body.removeEventListener("touchcancel",up,true);
		}

		function down(evt){
			if(dragging){
				up(evt);
				return;
			}
			startX=evt.x;
			startY=evt.y;
			if(tgtPxy){
				orgX=tgtPxy.x;
				orgY=tgtPxy.y;
			}else {
				orgX=orgY=0;
			}
			dragging=false;
			document.body.addEventListener("mousemove",move,true);
			document.body.addEventListener("mouseup",up,{once:true,capture:true});
			document.body.addEventListener("touchmove",move,true);
			document.body.addEventListener("touchend",up,true);
			document.body.addEventListener("touchcancel",up,true);
		}


		valMap=pxy.$_pptMap;
		webObj=valMap[pptWebObjIdx];
		//webObj.draggable="true";
		webObj.addEventListener("mousedown",down,capture);
		webObj.addEventListener("touchstart",down,capture);
		return meta;
	};
}

//****************************************************************************
//:Scroll to show item:
//****************************************************************************
{
	//------------------------------------------------------------------------
	VFACT.scrollToShow=function(item,scrollBox=null,opts=null){
		let rectItem,rectBox,d,gap,ani,dx=0,dy=0;
		opts=opts||{x:1,y:1};
		ani=!!opts.smooth;
		gap=opts.gap||0;
		scrollBox=scrollBox||item.parent;
		rectItem=item.getBoundingClientRect();
		rectBox=scrollBox.getBoundingClientRect();
		if(opts.x){
			if(rectItem.x<rectBox.x+gap){
				d=(rectItem.x-gap-rectBox.x);
			}
			if(rectItem.x+rectItem.width+gap>rectBox.x+rectBox.width){
				d=(rectItem.x+rectItem.width+gap-rectBox.x-rectBox.width);
			}
			dx=d||0;
			//scrollBox.webObj.scrollLeft+=d||0;
		}
		if(opts.y){
			if(rectItem.y<rectBox.y+gap){
				d=(rectItem.y-gap-rectBox.y);
			}
			if(rectItem.y+rectItem.height+gap>rectBox.y+rectBox.height){
				d=(rectItem.y+rectItem.height+gap-rectBox.y-rectBox.height);
			}
			dy=d||0;
			//scrollBox.webObj.scrollTop+=d||0;
		}
		if(dx||dy){
			scrollBox.webObj.scrollBy({top:dy,left:dx,behavior:ani?"smooth":"instant"});
		}
	};
}

//****************************************************************************
//:Fonts
//****************************************************************************
{
	//------------------------------------------------------------------------
	VFACT.loadFont=async function(name,url,options){
		let fontFace,loadedFace;
		try{
			fontFace=new FontFace(name,url,options);
			loadedFace=await fontFace.load();
			document.fonts.add(loadedFace);
		}catch(err){
			console.error("Load font error:");
			console.error(err);
		}
	};
}

//****************************************************************************
//:ShowList
//****************************************************************************
{
	//------------------------------------------------------------------------
	VFACT.dataList2View=function(view,list,defFunc,clear=true,watchFunc=null){
		let items,obj,css,i,n,item;
		items=[];
		if(clear){
			view.clearChildren();
		}
		n=list.length;
		for(i=0;i<n;i++){
			obj=list[i];
			css=defFunc(obj,i,view);
			if(css){
				css.position="relative";
				css.dataObj=obj;
				item=view.appendNewChild(css);
				if(watchFunc && watchFunc(item)===false){
					view.removeChild(item);
				}else {
					items.push(item);
				}
			}
		}
		return items;
	};

	//------------------------------------------------------------------------
	VFACT.syncDataList2View=function(view,list,defFunc,clear=false){
		let items,obj,css,i,n,j,m,item,bkItems,idx,nxt,rItems;
		if((!view)||(!list)||(!defFunc)){
			if(view && clear){
				view.clearChildren();
			}
			return [];
		}
		if(clear){
			return VFACT.dataList2View(view,list,defFunc,true,null);
		}
		rItems=[];
		bkItems=[];
		n=list.length;
		for(i=0;i<n;i++){
			obj=list[i];
			item=items[i];
			nxt=items[i+1]||null;
			if(item.dataObj===obj){
				rItems.push(item);
				continue;
			}
			
			//Check back-up:
			idx=bkItems.findIdx((hud)=>hud.dataObj===obj);
			if(idx>=0){
				item=bkItems[item];
				bkItems.splice(idx,1);
				view.insertBefore(item,nxt);
				item.release();
				rItems.push(item);
			}
			item.hold();
			bkItems.push(item);
			view.removeChild(item);
			items=view.children;
			m=items.length;
			//Check reset items:
			for(j=i;j<m;j++){
				item=items[j];
				if(item.dataObj===obj){
					item.hold();
					view.removeChild(item);
					view.insertBefore(item,nxt);
					item.release();
					rItems.push(item);
					break;
				}
			}
			//Create new item:			
			css=defFunc(obj,i,view);
			if(css){
				css.position="relative";
				css.dataObj=obj;
				item=view.appendNewChild(css);
				rItems.push(item);
			}
		}
		n=bkItems.length;
		for(i=0;i<n;i++){
			bkItems[i].release();
		}
		bkItems.splice(0);
		return rItems;
	};
}

//----------------------------------------------------------------------------
//Tree-Node
let setupTreeNode=function(typeDef){
	let getMap;
	getMap=typeDef.getMap;
	
	typeDef.defineIdxOnlyPpt("ownerNode",null,false);
	let pptHudIdx=typeDef.allocPptIdx("hud",null);
	typeDef.defineIdxOnlyPpt("nodeObj",null,false);
	typeDef.defineIdxOnlyPpt("isOpen",false,false);
	typeDef.defineIdxOnlyPpt("indentW",0,false);
	typeDef.defineIdxOnlyPpt("indent",0,false);
	
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(obj,def,webObj,styleObj,valMap){
		if(oldPrefix){
			oldPrefix.call(typeDef,obj,def,webObj,styleObj,valMap);
		}
		obj.autoLayout=true;
		return def;
	};
	//************************************************************************
	//define ppts:
	//************************************************************************
	let _setHud;
	{
		//ppt hud:
		{
			let _set;
			_set=_setHud=function(valMap,val){
				let curHud=valMap[pptHudIdx];
				let webObj=valMap[pptWebObjIdx];
				if(curHud===val){
					return;
				}
				if(curHud){
					webObj.removeChild(curHud.$_webObj);
					curHud.release();
				}
				curHud=valMap[pptHudIdx]=val;
				if(curHud){
					webObj.appendChild(curHud.$_webObj);
					curHud.hold();
				}
			};
			let _get=function(valMap){
				return valMap[pptHudIdx];
			};
			typeDef.definePpt("hud",_get,_set,false);
		}
	}
	//************************************************************************
	//overload functions:
	//************************************************************************
	{
		let appendChild=function(valMap){
			return (hud)=>{
				return _setHud(valMap,hud);
			};
		};
		typeDef.definePpt("appendChild",appendChild,null,false);
		
		typeDef.defineFunction("clearChildren",function(){
			let valMap=this;
			let curHud=valMap[pptHudIdx];
			let webObj=valMap[pptWebObjIdx];
			if(curHud){
				webObj.removeChild(curHud.$_webObj);
				curHud.release();
			}
			valMap[pptHudIdx]=null;
		});
		
		typeDef.defineFunction("doLayout",function(){
			let valMap=this;
			let curHud=valMap[pptHudIdx];
			if(curHud){
				curHud.doLayout();
			}
		});
			
		//------------------------------------------------------------------------
		let getClientW=function(valMap){
			let webObj,prtNode;
			webObj=valMap[pptWebObjIdx];
			prtNode=webObj.parentNode;
			if(!prtNode){
				return 0;
			}
			if(prtNode.offsetParent){
				return prtNode.clientWidth;
			}
			return 0;
		};
		getMap.set("clientW",getClientW);
		getMap.set("clientWidth",getClientW);
		
		//------------------------------------------------------------------------
		let getClientH=function(valMap){
			let webObj,prtNode;
			webObj=valMap[pptWebObjIdx];
			prtNode=webObj.parentNode;
			if(!prtNode){
				return 0;
			}
			if(prtNode.offsetParent){
				return prtNode.clientHeight;
			}
			return 0;
		};
		getMap.set("clientH",getClientH);
		getMap.set("clientHeight",getClientH);
		
		typeDef.defineFunction("showFace",function(...args){
			let valMap=this;
			let curHud=valMap[pptHudIdx];
			if(curHud){
				curHud.showFace(...args);
			}
		});
	}
};
let typeTreeNode=new TypeDef("treeNode",{"position":"relative","box-sizing":"border-box"});
VFACTObj.setupBasic(typeTreeNode);
setupTreeNode(typeTreeNode);

//----------------------------------------------------------------------------
//Tree:
let setupTree=function(typeDef,isJAX=false){
	let getMap;
	
	let codeFocus=isJAX?"hot":"focus";
	let codeBlur=isJAX?"normal":"blur";
	let codeSelect=isJAX?"selected":"select";
	
	getMap=typeDef.getMap;
	
	typeDef.defineIdxOnlyPpt("indent",20,false);
	let pptNodeGapIdx=typeDef.defineIdxOnlyPpt("nodeGap",0,false);
	let pptNodeDefIdx=typeDef.defineIdxOnlyPpt("nodeDef",null,false);
	let pptGetSubObjsIdx=typeDef.defineIdxOnlyPpt("getSubObjs",null,false);
	let pptHotNodeIdx=typeDef.allocPptIdx("hotNode",null);
	let pptSelectedIdx=typeDef.allocPptIdx("selected",null);
	let pptMultiSelectIdx=typeDef.defineIdxOnlyPpt("multiSelect",false,false);
	let pptPauseCallbackIdx=typeDef.defineIdxOnlyPpt("pauseCallback",0,false);
	let setHotNode,_clearSelects;
	
	let removeChild=getMap.get("removeChild")(null);
	
	let oldPrefix=typeDef.prefix;
	typeDef.prefix=function(obj,def,webObj,styleObj,valMap){
		if(oldPrefix){
			oldPrefix.call(typeDef,obj,def,webObj,styleObj,valMap);
		}
		valMap[pptSelectedIdx]=new Set();
		return def;
	};
	
	//************************************************************************
	//define ppts:
	//************************************************************************
	{
		//ppt headSpace
		{
			let pptIdx=typeDef.getPptIdx("padding",0);
			let _set=function(valMap,val){
				let padding=valMap[pptIdx];
				let styleObj=valMap[pptStyleObjIdx];
				if(padding>=0){
					padding=[val,padding,padding,padding];
				}else if(Array.isArray(padding)){
					padding[0]=val;
				}else {
					padding=[val,0,0,0];
				}
				styleObj.padding=`${padding[0]}px ${padding[1]}px ${padding[2]}px ${padding[3]}px`;
			};
			let _get=function(valMap){
				let padding=valMap[pptIdx];
				if(padding>=0){
					return padding;
				}else if(Array.isArray(padding)){
					return padding[0];
				}
				return 0;
			};
			typeDef.definePpt("headSpace",_get,_set,true);
		}
		
		//ppt endSpace
		{
			let pptIdx=typeDef.getPptIdx("padding");
			let _set=function(valMap,val){
				let padding=valMap[pptIdx];
				let styleObj=valMap[pptStyleObjIdx];
				if(padding>=0){
					padding=[padding,padding,val,padding];
				}else if(Array.isArray(padding)){
					padding[3]=val;
				}else {
					padding=[0,0,val,0];
				}
				styleObj.padding=`${padding[0]}px ${padding[1]}px ${padding[2]}px ${padding[3]}px`;
			};
			let _get=function(valMap){
				let padding=valMap[pptIdx];
				if(padding>=0){
					return padding;
				}else if(Array.isArray(padding)){
					return padding[3];
				}
				return 0;
			};
			typeDef.definePpt("endSpace",_get,_set,true);
		}
		
		//ppt nodes: proxy for nodes
		{
			let pptNodesIdx=typeDef.allocPptIdx("nodes",null);
			let getNodes=function(valMap,val){
				let nodes,webNodes;
				nodes=valMap[pptNodesIdx];
				if(nodes){
					return nodes;
				}
				webNodes=valMap[pptWebObjIdx].childNodes;
				nodes=new Proxy(webNodes,{
					get:function(obj,pName){
						if(pName>=0){
							return webNodes[pName].$_pxy;
						}
						if(pName==="length"){
							return webNodes.length;
						}
					}
				});
				valMap[pptNodesIdx]=nodes;
				return nodes;
			};
			getMap.set("nodes",getNodes);
		}
		
		//ppt hotNode
		{
			//will be replaced for JAXPatch
			setHotNode=function(valMap,val,addSel=0){
				let curHot=valMap[pptHotNodeIdx];
				let multi=valMap[pptMultiSelectIdx];
				let selSet=valMap[pptSelectedIdx];
				let pxy=valMap[pptProxyIdx];
				if(val===curHot){
					return;
				}
				if(curHot){
					if(selSet.has(curHot)){
						curHot.hud && curHot.hud.showFace(codeSelect);//will be replaced for JAXPatch
					}else {
						curHot.hud && curHot.hud.showFace(codeBlur);//will be replaced for JAXPatch
					}
				}
				valMap[pptHotNodeIdx]=curHot=val;
				if(curHot){
					if(multi && addSel){
						selSet.add(curHot);
						curHot.hud && curHot.hud.showFace(codeFocus);
						if(!valMap[pptPauseCallbackIdx]){
							pxy.OnSelNodeChange && pxy.OnSelNodeChange();
						}
					}else {
						valMap[pptPauseCallbackIdx]++;
						_clearSelects(valMap);
						valMap[pptPauseCallbackIdx]--;
						selSet.add(curHot);
						if(!valMap[pptPauseCallbackIdx]){
							pxy.OnSelNodeChange && pxy.OnSelNodeChange();
						}
						curHot.hud && curHot.hud.showFace(codeFocus);
					}
				}else {
					if(!multi || !addSel){
						_clearSelects(valMap);
					}
				}
				pxy.OnHotNodeChange && pxy.OnHotNodeChange(curHot);
			};
			let _get=function(valMap){
				return valMap[pptHotNodeIdx];
			};
			typeDef.definePpt("hotNode",_get,setHotNode,false);
			typeDef.defineFunction("setHotNode",function(node,addSel){
				setHotNode(this,node,addSel);
			});
		}
		
		//ppt selected
		{
			let _get=function(valMap){
				return valMap[pptSelectedIdx];
			};
			typeDef.definePpt("selected",_get,null,false);
		}
	}
	
	//************************************************************************
	//define functions:
	//************************************************************************
	{
		//--------------------------------------------------------------------
		//tree.clear():
		{
			typeDef.defineFunction("clear",function(){
				let valMap=this;
				let obj,subpxy,pxy;
				valMap[pptWebObjIdx];
				pxy=valMap[pptProxyIdx];
				setHotNode(valMap,null);
				_clearSelects(valMap);
				while(obj=pxy.firstChild){
					removeChild.call(valMap,obj);
					subpxy=obj.$_pxy;
					if(subpxy){
						subpxy.release();
					}
				}
			});
		}
		
		//--------------------------------------------------------------------
		//tree.addNode(newNodeObj,ownerNode,hud=null):
		let _addNode=function(valMap,obj,upNode,hudDef){
			let node,checkDiv,checkPxy,upIndent;
			let nodeDefFunc=valMap[pptNodeDefIdx];
			let pxy=valMap[pptProxyIdx];
			if(!upNode){
				node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},pxy);
				node.margin=[0,0,valMap[pptNodeGapIdx],0];
				node.nodeObj=obj;
				node.indent=0;
				if(!hudDef){
					hudDef=nodeDefFunc(obj,node,pxy);
				}
				hudDef.position="relative";
				VFACT.createObj(hudDef,node);
				return node;
			}
			upIndent=upNode.indent;
			checkDiv=upNode.$_webObj.nextSibling;
			while(checkDiv){
				checkPxy=checkDiv.$_pxy;
				if(checkPxy && checkPxy.indent<=upIndent){
					node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},pxy,checkPxy);
					node.margin=[0,0,valMap[pptNodeGapIdx],0];
					node.nodeObj=obj;
					node.indent=upIndent+1;
					if(!hudDef){
						hudDef=nodeDefFunc(obj,node,pxy);
					}
					hudDef.position="relative";
					VFACT.createObj(hudDef,node);
					return node;
				}
				checkDiv=checkDiv.nextSibling;
			}
			//Add to end:
			node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},pxy);
			node.margin=[0,0,valMap[pptNodeGapIdx],0];
			node.nodeObj=obj;
			node.indent=upIndent+1;
			if(!hudDef){
				hudDef=nodeDefFunc(obj,node,pxy);
			}
			hudDef.position="relative";
			VFACT.createObj(hudDef,node);
			return node;
		};
		
		{
			typeDef.defineFunction("addNode",function(obj,upNode,hudDef){
				return _addNode(this,obj,upNode,hudDef);
			});
		}
	}
	
	//------------------------------------------------------------------------
	//tree.addNodes(list,upNode)
	let _addNodes;
	{
		_addNodes=function(valMap,list,upNode){
			let node,hudDef,obj,upIndent,checkDiv,checkPxy;
			let nodeDefFunc=valMap[pptNodeDefIdx];
			let gap=valMap[pptNodeGapIdx];
			let pxy=valMap[pptProxyIdx];
			let webObj=valMap[pptWebObjIdx];
			let frg=new DocumentFragment();
			frg.$_pxy=pxy;
			frg.offsetParent=webObj.offsetParent;
			frg.clientWidth=webObj.clientWidth;
			frg.clientHeight=webObj.clientHeight;
			/*frg.clientW=pxy.clientW;
			frg.clientH=pxy.clientH;*/
			if(!upNode){
				for(obj of list){
					node=VFACT.createObj({type:"treeNode",w:"100%",h:"",ownerNode:upNode,autoLayout:1},frg);
					node.margin=[0,0,gap,0];
					node.nodeObj=obj;
					node.indent=0;
					hudDef=nodeDefFunc(obj,node,pxy);
					hudDef.position="relative";
					VFACT.createObj(hudDef,node);
				}
				webObj.appendChild(frg);
				return;
			}
			upIndent=upNode.indent;
			checkDiv=upNode.$_webObj.nextSibling;
			while(checkDiv){
				checkPxy=checkDiv.$_pxy;
				if(checkPxy && checkPxy.indent<=upIndent){
					for(obj of list){
						//node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode},pxy,checkPxy);
						node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},frg);
						node.margin=[0,0,gap,0];
						node.nodeObj=obj;
						node.indent=upIndent+1;
						hudDef=nodeDefFunc(obj,node,pxy);
						hudDef.position="relative";
						VFACT.createObj(hudDef,node);
					}
					webObj.insertBefore(frg,checkPxy.$_webObj);
					return;
				}
				checkDiv=checkDiv.nextSibling;
			}
			//Add to end:
			for(obj of list){
				node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},frg);
				//node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode},pxy);
				node.margin=[0,0,gap,0];
				node.nodeObj=obj;
				node.indent=upIndent+1;
				hudDef=nodeDefFunc(obj,node,pxy);
				hudDef.position="relative";
				VFACT.createObj(hudDef,node);
			}
			webObj.appendChild(frg);
		};
		{
			typeDef.defineFunction("addNodes",function(list,upNode){
				let valMap=this;
				_addNodes(valMap,list,upNode);
			});
		}
	}
	
	//------------------------------------------------------------------------
	//tree.insertNode(idx,obj,upNode,hud)
	{
		let _insertNode=function(valMap,idx,obj,upNode,hud){
			let checkNode,upIndent,checkIndent;
			let node,hudDef;
			let nodeDefFunc=valMap[pptNodeDefIdx];
			let pxy=valMap[pptProxyIdx];
			upIndent=upNode.indent;
			checkIndent=upIndent+1;
			checkNode=upNode.nextSibling;
			while(checkNode){
				if(idx===0){
					break;
				}
				if(checkNode.indent<=upIndent){
					break;
				}
				if(checkNode.indent===checkIndent){
					idx--;
				}
				checkNode=checkNode.nextSibling;
			}
			//appendNode before checkNode:
			node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},pxy,checkNode||null);
			node.margin=[0,0,valMap[pptNodeGapIdx],0];
			node.nodeObj=obj;
			node.indent=upIndent+1;
			if(hud){
				node.hud=hud;
			}else {
				hudDef=nodeDefFunc(obj,node,pxy);
				hudDef.position="relative";
				VFACT.createObj(hudDef,node);
			}
			return node;
		};
		{
			typeDef.defineFunction("insertNode",function(idx,obj,upNode,hud){
				return _insertNode(this,idx,obj,upNode,hud);
			});
		}
	}
	
	//------------------------------------------------------------------------
	//tree.insertNodeBefore(obj,beforeNode,hud)
	{
		let _insertNodeBefore=function(valMap,obj,beforeNode,hud){
			let upNode,node,hudDef;
			let nodeDefFunc=valMap[pptNodeDefIdx];
			let pxy=valMap[pptProxyIdx];
			upNode=beforeNode.ownerNode;
			node=VFACT.createObj({type:"treeNode",position:"relative",x:0,y:0,w:"100%",h:"",ownerNode:upNode,autoLayout:1},pxy,beforeNode);
			node.margin=[0,0,valMap[pptNodeGapIdx],0];
			node.nodeObj=obj;
			node.indent=beforeNode.indent;
			if(hud){
				node.hud=hud;
			}else {
				hudDef=nodeDefFunc(obj,node,pxy);
				hudDef.position="relative";
				hud=VFACT.createObj(hudDef,node);
			}
			return node;
		};
		{
			typeDef.defineFunction("insertNodeBefore",function (obj,beforeNode,hud){
				return _insertNodeBefore(this,obj,beforeNode,hud);
			});
		}
	}
	
	//------------------------------------------------------------------------
	//tree.replaceNode(newObj,oldNode,hud)
	{
		let _replaceNode=function(valMap,newObj,node,hud){
			let hudDef,hotNode,selSet;
			let pxy=valMap[pptProxyIdx];
			node.nodeObj=newObj;
			if(hud){
				node.hud=hud;
			}else {
				let nodeDefFunc=valMap[pptNodeDefIdx];
				hudDef=nodeDefFunc(newObj,node,pxy);
				hudDef.position="relative";
				hud=VFACT.createObj(hudDef,node);
			}
			hotNode=valMap[pptHotNodeIdx];
			selSet=valMap[pptSelectedIdx];
			if(hotNode===node){
				hud.showFace(codeFocus);
			}else if(selSet.has(node)){
				hud.showFace(codeSelect);
			}
			return node;
		};
		
		typeDef.defineFunction("replaceNode",function(newObj,node,hud){
			return _replaceNode(this,newObj,node,hud);
		});
	}
	
	//------------------------------------------------------------------------
	//tree.removeNode(node)
	{
		let _removeNode=function(valMap,node){
			let hotNode,selSet;
			hotNode=valMap[pptHotNodeIdx];
			selSet=valMap[pptSelectedIdx];
			if(hotNode===node){
				setHotNode(valMap,null,1);
			}
			selSet.delete(node);
			node.hud=null;
			removeChild.call(valMap,node);
		};
		typeDef.defineFunction("removeNode",function(node){
			_removeNode(this,node);
		});
	}
	
	//------------------------------------------------------------------------
	//tree.getNodeHud(node)
	{
		typeDef.defineFunction("getNodeHud",function(node){
			return node.hud;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.getNodeOfObj(obj)
	{
		let _getNodeOfObj=function(valMap,obj){
			let checkNode;
			let pxy=valMap[pptProxyIdx];
			checkNode=pxy.firstChild;
			while(checkNode){
				if(checkNode.nodeObj===obj){
					return checkNode;
				}
				checkNode=checkNode.nextSibling;
			}
			return null;
		};
		typeDef.defineFunction("getNodeOfObj",function(obj){
			return _getNodeOfObj(this,obj);
			
		});
	}
	
	//------------------------------------------------------------------------
	//tree.getNodeIdxOfObj(obj)
	{
		typeDef.defineFunction("getNodeIdxOfObj",function(obj){
			let valMap=this;
			let checkNode,idx=0;
			let pxy=valMap[pptProxyIdx];
			checkNode=pxy.firstChild;
			while(checkNode){
				if(checkNode.nodeObj===obj){
					return idx;
				}
				idx++;
				checkNode=checkNode.nextSibling;
			}
			return -1;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.indexOfNode(node)
	{
		typeDef.defineFunction("indexOfNode",function(node){
			let valMap=this;
			let list,nodeWebObj,idx,n;
			let webObj=valMap[pptWebObjIdx];
			nodeWebObj=node.$_webObj;
			list=webObj.childNodes;
			n=list.length;
			for(idx=0;idx<n;idx++){
				if(list[idx]===nodeWebObj){
					return idx;
				}
			}
			return -1;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.openNode(node)
	let _openNode;
	{
		_openNode=function(node){
			let valMap=this;
			let getSubsFunc,subs;
			if(node.isOpen){
				return;
			}
			getSubsFunc=valMap[pptGetSubObjsIdx];
			if(!getSubsFunc){
				return;
			}
			subs=getSubsFunc(node.nodeObj,node);
			if(Array.isArray(subs) && subs.length>0){
				_addNodes(valMap,subs,node);
			}
			node.isOpen=true;
			node.hud && node.hud.showFace("open");
		};
		typeDef.defineFunction("openNode",_openNode);
	}
	
	//------------------------------------------------------------------------
	//tree.closeNode(node)
	let _closeNode;
	{
		_closeNode=function(node){
			let valMap=this;
			let checkNode,indent,hotNode,selSet,pauseCallback,selChanged;
			if(!node.isOpen){
				return;
			}
			let pxy=valMap[pptProxyIdx];
			node.isOpen=false;
			node.hud && node.hud.showFace("close");
			checkNode=node.nextSibling;
			indent=node.indent;
			hotNode=valMap[pptHotNodeIdx];
			selSet=valMap[pptSelectedIdx];
			pauseCallback=valMap[pptPauseCallbackIdx];
			selChanged=0;
			while(checkNode){
				if(checkNode.indent<=indent){
					break;
				}
				if(checkNode===hotNode){
					hotNode=null;
					setHotNode(valMap,null,1);
				}
				if(selSet.has(checkNode)){
					selSet.delete(checkNode);
					selChanged=1;
				}
				node=checkNode;
				checkNode=node.nextSibling;
				removeChild.call(valMap,node);
			}
			if(selChanged && !pauseCallback){
				pxy.OnSelNodeChange && pxy.OnSelNodeChange();
			}
		};
		typeDef.defineFunction("closeNode",_closeNode);
	}
	
	//------------------------------------------------------------------------
	//tree.clearSelects()
	{
		_clearSelects=function(valMap){
			let selSet,node,selChanged,pauseCallback;
			let hotNode;
			let pxy=valMap[pptProxyIdx];
			selSet=valMap[pptSelectedIdx];
			pauseCallback=valMap[pptPauseCallbackIdx];
			selChanged=0;
			for(node of selSet){
				selChanged=1;
				node.hud && node.hud.showFace(codeBlur);
			}
			selSet.clear();
			if(selChanged && !pauseCallback){
				pxy.OnSelNodeChange && pxy.OnSelNodeChange();
			}
			hotNode=valMap[pptHotNodeIdx];
			if(hotNode){
				hotNode.showFace(codeFocus);
			}
		};
		let funcIdx=typeDef.allocPptIdx("clearSelects()",null);
		let clearSelects=function(valMap){
			let func;
			func=valMap[funcIdx];
			if(!func){
				func=valMap[funcIdx]=()=>{
					_clearSelects(valMap);
				};
			}
			return func;
		};
		getMap.set("clearSelects",clearSelects);
	}
	
	//------------------------------------------------------------------------
	//tree.selectNode(node)
	{
		typeDef.defineFunction("selectNode",function (node) {
			let valMap=this;
			let selSet,hotNode,pauseCallback;
			let pxy=valMap[pptProxyIdx];
			pauseCallback=valMap[pptPauseCallbackIdx];
			selSet=valMap[pptSelectedIdx];
			hotNode=valMap[pptHotNodeIdx];
			if(selSet.has(node)){
				return;
			}
			selSet.add(node);
			if(node!==hotNode){
				node.hud && node.hud.showFace(codeSelect);
			}
			if(!pauseCallback){
				pxy.OnSelNodeChange && pxy.OnSelNodeChange();
			}
		});
	}
	
	//------------------------------------------------------------------------
	//tree.selectAll()
	{
		typeDef.defineFunction("selectAll",function () {
			let valMap=this;
			let selSet,hotNode,pauseCallback;
			let pxy=valMap[pptProxyIdx];
			let list,node,n,idx,webObj;
			webObj=valMap[pptWebObjIdx];
			pauseCallback=valMap[pptPauseCallbackIdx];
			selSet=valMap[pptSelectedIdx];
			hotNode=valMap[pptHotNodeIdx];
			list=webObj.childNodes;
			n=list.length;
			for(idx=0;idx<n;idx++){
				node=list[idx];
				selSet.add(node);
				if(node!==hotNode){
					node.hud && node.hud.showFace(codeSelect);
				}
			}
			if(!pauseCallback){
				pxy.OnSelNodeChange && pxy.OnSelNodeChange();
			}
		});
	}

	//------------------------------------------------------------------------
	//tree.deselectNode(node)
	{
		typeDef.defineFunction("deselectNode",function (node) {
			let valMap=this;
			let selSet,hotNode,pauseCallback;
			let pxy=valMap[pptProxyIdx];
			pauseCallback=valMap[pptPauseCallbackIdx];
			selSet=valMap[pptSelectedIdx];
			hotNode=valMap[pptHotNodeIdx];
			if(!selSet.has(node)){
				return;
			}
			selSet.delete(node);
			if(node===hotNode){
				valMap[pptHotNodeIdx]=null;
				node.hud && node.hud.showFace(codeBlur);
				pxy.OnHotNodeChange && pxy.OnHotNodeChange(null);
			}else {
				node.hud && node.hud.showFace(codeBlur);
			}
			if(!pauseCallback){
				pxy.OnSelNodeChange && pxy.OnSelNodeChange();
			}
		});
	}
	
	//------------------------------------------------------------------------
	//tree.isNodeSelected(node)
	{
		typeDef.defineFunction("isNodeSelected",function (node) {
			let valMap=this;
			let selSet;
			selSet=valMap[pptSelectedIdx];
			return selSet.has(node);
		});
	}
	
	//------------------------------------------------------------------------
	//tree.findNode(func)
	{
		typeDef.defineFunction("findNode",function (func) {
			let valMap=this;
			let checkNode;
			let pxy=valMap[pptProxyIdx];
			checkNode=pxy.firstChild;
			while(checkNode){
				if(func(checkNode)){
					return checkNode;
				}
				checkNode=checkNode.nextSibling;
			}
			return null;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.getNodeNum()
	{
		typeDef.defineFunction("getNodeNum",function () {
			return this[pptWebObjIdx].childNodes.length;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.sortNodes(nodeList)
	{
		typeDef.defineFunction("sortNodes",function (list) {
			let valMap=this;
			let nodeWebObjs,i,n,tgtList;
			nodeWebObjs=valMap[pptWebObjIdx].childNodes;
			n=nodeWebObjs.length;
			for(i=0;i<n;i++){
				nodeWebObjs[i].nodeIdx=i;
			}
			tgtList=list.map(item=>item.$_webObj);
			tgtList.sort((a,b)=>{
				return a.nodeIdx-b.nodeIdx;
			});
			return tgtList.map(item=>item.$_pxy);
		});
	}
	
	let _insertBefore=getMap.get("insertBefore")(null);
	//------------------------------------------------------------------------
	//tree.moveNodeUp(node)
	{
		typeDef.defineFunction("moveNodeUp",function(node){
			let valMap=this;
			let preNode,curOpen;
			preNode=node.previousSibling;
			if(!preNode || preNode.indent<node.indent){
				return false;
			}
			while(preNode && preNode.indent>node.indent){
				preNode=preNode.ownerNode;
			}
			if(!preNode||preNode.indent!==node.indent){
				return false;//impossible...
			}
			curOpen=node.isOpen;
			if(curOpen){
				_closeNode.call(valMap,node);
			}
			_insertBefore.call(valMap,node,preNode);
			if(curOpen){
				_openNode.call(valMap,node);
			}
			return true;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.moveNodeDown(node)
	{
		typeDef.defineFunction("moveNodeDown",function(node){
			let valMap=this;
			let nextNode,nextOpen,curOpen;
			curOpen=node.isOpen;
			if(curOpen){
				_closeNode.call(valMap,node);
			}
			nextNode=node.nextSibling;
			if(!nextNode){// || nextNode.indent!==node.indent){
				return false;
			}
			if(nextNode.indent<node.indent){
				return false;//This is the last node:
			}
			nextOpen=nextNode.isOpen;
			if(nextOpen){
				_closeNode.call(valMap,nextNode);
			}
			_insertBefore.call(valMap,nextNode,node);
			if(nextOpen){
				_openNode.call(valMap,nextNode);
			}
			if(curOpen){
				_openNode.call(valMap,node);
			}
			return true;
		});
	}
	
	//------------------------------------------------------------------------
	//tree.isNodeInView(node)
	{
		typeDef.defineFunction("isNodeInView",function (node) {
			let valMap=this;
			let div,overTop,overBtm;
			let webObj=valMap[pptWebObjIdx];
			div=node.$_webObj;
			overTop = div.offsetTop - webObj.offsetTop < webObj.scrollTop;
			overBtm =  (div.offsetTop - webObj.offsetTop + div.clientHeight) > (webObj.scrollTop + webObj.clientHeight);
			return !(overTop||overBtm);
		});
	}
	
	//------------------------------------------------------------------------
	//tree.scrollShowNode(node)
	{
		typeDef.defineFunction("scrollShowNode",function(node){
			let valMap=this;
			let div;
			let overTop,overBtm;
			div=node.$_webObj;
			let webObj=valMap[pptWebObjIdx];
			overTop = div.offsetTop - webObj.offsetTop < webObj.scrollTop;
			overBtm =  (div.offsetTop - webObj.offsetTop + div.clientHeight) > (webObj.scrollTop + webObj.clientHeight);
			
			if(overTop){
				div.scrollIntoView(true);
			}else if(overBtm){
				div.scrollIntoView(false);
			}
		});
	}
	
	//------------------------------------------------------------------------
	//overload: hudObj.appendChild
	{
		typeDef.defineFunction("appendChild",function(obj){
			let valMap=this;
			let subWebObj,prePrt;
			if(obj.$_type!==typeTreeNode){
				return null;
			}
			subWebObj=obj.$_webObj;
			prePrt=subWebObj.parentNode;
			if(prePrt){
				prePrt=prePrt.$_pxy;
			}
			valMap[pptWebObjIdx].appendChild(subWebObj);
			obj.doLayout();
			if(!prePrt){
				obj.addRefCount();
			}
			return obj;
		});
	}
	
	//------------------------------------------------------------------------
	//overload: hudObj.appendNewChild
	{
		getMap.delete("appendNewChild");
	}
	
	//------------------------------------------------------------------------
	//overload: hudObj.insertBefore
	{
		typeDef.defineFunction("insertBefore",function(obj1,obj2){
			let valMap=this;
			let webObj1,prePrt;
			if(obj1.$_type!==typeTreeNode){
				return null;
			}
			webObj1=obj1.$_webObj;
			prePrt=webObj1.parentNode;
			if(prePrt){
				prePrt=prePrt.$_pxy;
			}
			obj1=valMap[pptWebObjIdx].insertBefore(webObj1,obj2.$_webObj).$_pxy;
			obj1.doLayout();
			if(!prePrt){
				obj1.addRefCount();
			}
			return obj1;
		});
	}
	
	//------------------------------------------------------------------------
	//overload: hudObj.removeChild
	getMap.delete("removeChild");
	
	//------------------------------------------------------------------------
	//overload: hudObj.replaceChild
	getMap.delete("replaceChild");
	
	//------------------------------------------------------------------------
	//overload: hudObj.clearChildren
	//getMap.delete("clearChildren");
	getMap.set("clearChildren",getMap.get("clear"));
	
	//------------------------------------------------------------------------
	//hudObj.execInTree(func)
	{
		typeDef.defineFunction("execInTree",function(func){
			let valMap=this;
			let list,i,n,subObj,subExec;
			let pxy=valMap[pptProxyIdx];
			let webObj=valMap[pptWebObjIdx];
			func(pxy);
			list=webObj.childNodes;
			n=list.length;
			for(i=0;i<n;i++){
				subObj=list[i].$_pxy;
				if(subObj){
					subObj=subObj.hud;
					if(subObj){
						subExec=subObj.execInTree;
						if(subExec){
							subExec.call(subObj,func);
						}else {
							func(subObj);
						}
					}
				}
			}
		});
	}
};
VFACTObj.setupTree=setupTree;

//animate function:
VFACT.animate=VFACTAni.animate;

//Define basic VFACT components:
let typeObj$1=new TypeDef("obj",{position:"absolute"});
VFACTObj.setupBasic(typeObj$1);
VFACTObj.setupHierarchy(typeObj$1);
VFACTObj.setupFaces(typeObj$1);
VFACTObj.setupClick(typeObj$1);
TypeDef.aliasType("obj","view");
TypeDef.aliasType("obj","hud");

let typeBox$1=new TypeDef("box",{position:"absolute"});
VFACTObj.setupBasic(typeBox$1);
VFACTObj.setupBox(typeBox$1,"rgba[255,255,255,1]");
VFACTObj.setupHierarchy(typeBox$1);
VFACTObj.setupFaces(typeBox$1);
VFACTObj.setupClick(typeBox$1);

let typeJAXImage$1=new TypeDef("image",{position:"absolute"});
VFACTObj.setupBasic(typeJAXImage$1);
VFACTObj.setupImage(typeJAXImage$1);
VFACTObj.setupHierarchy(typeJAXImage$1);
VFACTObj.setupFaces(typeJAXImage$1);
VFACTObj.setupClick(typeJAXImage$1);

let typeJAXText$1=new TypeDef("text",{position:"absolute"});
VFACTObj.setupBasic(typeJAXText$1);
VFACTObj.setupText(typeJAXText$1);
//VFACTObj.setupHierarchy(typeJAXText);
VFACTObj.setupFaces(typeJAXText$1);
VFACTObj.setupClick(typeJAXText$1);

let typeJAXButton$1=new TypeDef("button",{position:"absolute"});
VFACTObj.setupBasic(typeJAXButton$1);
VFACTObj.setupHierarchy(typeJAXButton$1);
VFACTObj.setupFaces(typeJAXButton$1);
VFACTObj.setupClick(typeJAXButton$1);
VFACTObj.setupButton(typeJAXButton$1);
TypeDef.aliasType("button","btn");

let typeJAXEdit$1=new TypeDef("edit",{position:"absolute"});
VFACTObj.setupBasic(typeJAXEdit$1);
VFACTObj.setupNoneHierarchy(typeJAXEdit$1);
VFACTObj.setupFaces(typeJAXEdit$1);
VFACTObj.setupBox(typeJAXEdit$1);
VFACTObj.setupEdit(typeJAXEdit$1);

let typeJAXEditMemo$1=new TypeDef("memo",{position:"absolute"});
VFACTObj.setupBasic(typeJAXEditMemo$1);
VFACTObj.setupNoneHierarchy(typeJAXEditMemo$1);
VFACTObj.setupFaces(typeJAXEditMemo$1);
VFACTObj.setupBox(typeJAXEditMemo$1);
VFACTObj.setupEditMemo(typeJAXEditMemo$1);

let typeJAXDocker$1=new TypeDef("dock",{position:"absolute"});
VFACTObj.setupBasic(typeJAXDocker$1);
VFACTObj.setupHierarchy(typeJAXDocker$1);
VFACTObj.setupFaces(typeJAXDocker$1);
VFACTObj.setupDocker(typeJAXDocker$1);

let typeJAXTree$1=new TypeDef("tree",{position:"absolute",overFlow:"auto"});
VFACTObj.setupBasic(typeJAXTree$1);
VFACTObj.setupHierarchy(typeJAXTree$1);
VFACTObj.setupFaces(typeJAXTree$1);
VFACTObj.setupTree(typeJAXTree$1);

//animate function:
VFACT.animate=VFACTAni.animate;

//Define basic VFACT components:
let typeObj=new TypeDef("obj",{position:"absolute"});
VFACTObj.setupBasic(typeObj);
VFACTObj.setupHierarchy(typeObj);
VFACTObj.setupFaces(typeObj);
VFACTObj.setupClick(typeObj);
TypeDef.aliasType("obj","view");
TypeDef.aliasType("obj","hud");

let typeBox=new TypeDef("box",{position:"absolute"});
VFACTObj.setupBasic(typeBox);
VFACTObj.setupBox(typeBox,"rgba[255,255,255,1]");
VFACTObj.setupHierarchy(typeBox);
VFACTObj.setupFaces(typeBox);
VFACTObj.setupClick(typeBox);

let typeJAXImage=new TypeDef("image",{position:"absolute"});
VFACTObj.setupBasic(typeJAXImage);
VFACTObj.setupImage(typeJAXImage);
VFACTObj.setupHierarchy(typeJAXImage);
VFACTObj.setupFaces(typeJAXImage);
VFACTObj.setupClick(typeJAXImage);

let typeJAXText=new TypeDef("text",{position:"absolute"});
VFACTObj.setupBasic(typeJAXText);
VFACTObj.setupText(typeJAXText);
//VFACTObj.setupHierarchy(typeJAXText);
VFACTObj.setupFaces(typeJAXText);
VFACTObj.setupClick(typeJAXText);

let typeJAXButton=new TypeDef("button",{position:"absolute"});
VFACTObj.setupBasic(typeJAXButton);
VFACTObj.setupHierarchy(typeJAXButton);
VFACTObj.setupFaces(typeJAXButton);
VFACTObj.setupClick(typeJAXButton);
VFACTObj.setupButton(typeJAXButton);
TypeDef.aliasType("button","btn");

let typeJAXEdit=new TypeDef("edit",{position:"absolute"});
VFACTObj.setupBasic(typeJAXEdit);
VFACTObj.setupNoneHierarchy(typeJAXEdit);
VFACTObj.setupFaces(typeJAXEdit);
VFACTObj.setupBox(typeJAXEdit);
VFACTObj.setupEdit(typeJAXEdit);

let typeJAXEditMemo=new TypeDef("memo",{position:"absolute"});
VFACTObj.setupBasic(typeJAXEditMemo);
VFACTObj.setupNoneHierarchy(typeJAXEditMemo);
VFACTObj.setupFaces(typeJAXEditMemo);
VFACTObj.setupBox(typeJAXEditMemo);
VFACTObj.setupEditMemo(typeJAXEditMemo);

let typeJAXDocker=new TypeDef("dock",{position:"absolute"});
VFACTObj.setupBasic(typeJAXDocker);
VFACTObj.setupHierarchy(typeJAXDocker);
VFACTObj.setupFaces(typeJAXDocker);
VFACTObj.setupDocker(typeJAXDocker);

let typeJAXTree=new TypeDef("tree",{position:"absolute",overFlow:"auto"});
VFACTObj.setupBasic(typeJAXTree);
VFACTObj.setupHierarchy(typeJAXTree);
VFACTObj.setupFaces(typeJAXTree);
VFACTObj.setupTree(typeJAXTree);

//>>>>>>Node2Coke>>>>>>
var module$1$1={exports:{}};
var module$3=module$1$1;

function assertPath(path) {
	if (typeof path !== 'string') {
		throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
	}
}

// Resolves . and .. elements in a path with directory names
function normalizeStringPosix(path, allowAboveRoot) {
	var res = '';
	var lastSegmentLength = 0;
	var lastSlash = -1;
	var dots = 0;
	var code;
	for (var i = 0; i <= path.length; ++i) {
		if (i < path.length)
			code = path.charCodeAt(i);
		else if (code === 47 /*/*/)
			break;
		else
			code = 47 /*/*/;
		if (code === 47 /*/*/) {
			if (lastSlash === i - 1 || dots === 1) ; else if (lastSlash !== i - 1 && dots === 2) {
				if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
					if (res.length > 2) {
						var lastSlashIndex = res.lastIndexOf('/');
						if (lastSlashIndex !== res.length - 1) {
							if (lastSlashIndex === -1) {
								res = '';
								lastSegmentLength = 0;
							} else {
								res = res.slice(0, lastSlashIndex);
								lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
							}
							lastSlash = i;
							dots = 0;
							continue;
						}
					} else if (res.length === 2 || res.length === 1) {
						res = '';
						lastSegmentLength = 0;
						lastSlash = i;
						dots = 0;
						continue;
					}
				}
				if (allowAboveRoot) {
					if (res.length > 0)
						res += '/..';
					else
						res = '..';
					lastSegmentLength = 2;
				}
			} else {
				if (res.length > 0)
					res += '/' + path.slice(lastSlash + 1, i);
				else
					res = path.slice(lastSlash + 1, i);
				lastSegmentLength = i - lastSlash - 1;
			}
			lastSlash = i;
			dots = 0;
		} else if (code === 46 /*.*/ && dots !== -1) {
			++dots;
		} else {
			dots = -1;
		}
	}
	return res;
}

function _format(sep, pathObject) {
	var dir = pathObject.dir || pathObject.root;
	var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
	if (!dir) {
		return base;
	}
	if (dir === pathObject.root) {
		return dir + base;
	}
	return dir + sep + base;
}

var posix = {
	// path.resolve([from ...], to)
	resolve: function resolve() {
		var resolvedPath = '';
		var resolvedAbsolute = false;
		var cwd;
		
		for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
			var path;
			if (i >= 0)
				path = arguments[i];
			else {
				if (cwd === undefined)
					cwd = process.cwd();
				path = cwd;
			}
			
			assertPath(path);
			
			// Skip empty entries
			if (path.length === 0) {
				continue;
			}
			
			resolvedPath = path + '/' + resolvedPath;
			resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;
		}
		
		// At this point the path should be resolved to a full absolute path, but
		// handle relative paths to be safe (might happen when process.cwd() fails)
		
		// Normalize the path
		resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
		
		if (resolvedAbsolute) {
			if (resolvedPath.length > 0)
				return '/' + resolvedPath;
			else
				return '/';
		} else if (resolvedPath.length > 0) {
			return resolvedPath;
		} else {
			return '.';
		}
	},
	
	normalize: function normalize(path) {
		let isAbsolute,trailingSeparator;
		assertPath(path);
		
		if (path.length === 0) return '.';
		
		isAbsolute = path.charCodeAt(0) === 47 /*/*/;
		trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;
		
		// Normalize the path
		path = normalizeStringPosix(path, !isAbsolute);
		
		if (path.length === 0 && !isAbsolute) path = '.';
		if (path.length > 0 && trailingSeparator) path += '/';
		
		if (isAbsolute) return '/' + path;
		return path;
	},
	
	isAbsolute: function isAbsolute(path) {
		assertPath(path);
		return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;
	},
	
	join: function join() {
		if (arguments.length === 0)
			return '.';
		var joined;
		for (var i = 0; i < arguments.length; ++i) {
			var arg = arguments[i];
			assertPath(arg);
			if (arg.length > 0) {
				if (joined === undefined)
					joined = arg;
				else
					joined += '/' + arg;
			}
		}
		if (joined === undefined)
			return '.';
		return posix.normalize(joined);
	},
	
	joinTabOSURL: function join() {
		if (arguments.length === 0)
			return '.';
		var joined;
		for (var i = 0; i < arguments.length; ++i) {
			var arg = arguments[i];
			assertPath(arg);
			if (arg.length > 0) {
				if (joined === undefined)
					joined = arg;
				else
					joined += '/' + arg;
			}
		}
		if (joined === undefined)
			return '.';
		if(joined.startsWith("//")){
			return "/"+posix.normalize(joined);
		}
		return posix.normalize(joined);
	},

	relative: function relative(from, to) {
		assertPath(from);
		assertPath(to);
		
		if (from === to) return '';
		
		from = posix.resolve(from);
		to = posix.resolve(to);
		
		if (from === to) return '';
		
		// Trim any leading backslashes
		var fromStart = 1;
		for (; fromStart < from.length; ++fromStart) {
			if (from.charCodeAt(fromStart) !== 47 /*/*/)
				break;
		}
		var fromEnd = from.length;
		var fromLen = fromEnd - fromStart;
		
		// Trim any leading backslashes
		var toStart = 1;
		for (; toStart < to.length; ++toStart) {
			if (to.charCodeAt(toStart) !== 47 /*/*/)
				break;
		}
		var toEnd = to.length;
		var toLen = toEnd - toStart;
		
		// Compare paths to find the longest common path from root
		var length = fromLen < toLen ? fromLen : toLen;
		var lastCommonSep = -1;
		var i = 0;
		for (; i <= length; ++i) {
			if (i === length) {
				if (toLen > length) {
					if (to.charCodeAt(toStart + i) === 47 /*/*/) {
						// We get here if `from` is the exact base path for `to`.
						// For example: from='/foo/bar'; to='/foo/bar/baz'
						return to.slice(toStart + i + 1);
					} else if (i === 0) {
						// We get here if `from` is the root
						// For example: from='/'; to='/foo'
						return to.slice(toStart + i);
					}
				} else if (fromLen > length) {
					if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
						// We get here if `to` is the exact base path for `from`.
						// For example: from='/foo/bar/baz'; to='/foo/bar'
						lastCommonSep = i;
					} else if (i === 0) {
						// We get here if `to` is the root.
						// For example: from='/foo'; to='/'
						lastCommonSep = 0;
					}
				}
				break;
			}
			var fromCode = from.charCodeAt(fromStart + i);
			var toCode = to.charCodeAt(toStart + i);
			if (fromCode !== toCode)
				break;
			else if (fromCode === 47 /*/*/)
				lastCommonSep = i;
		}
		
		var out = '';
		// Generate the relative path based on the path difference between `to`
		// and `from`
		for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
			if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
				if (out.length === 0)
					out += '..';
				else
					out += '/..';
			}
		}
		
		// Lastly, append the rest of the destination (`to`) path that comes after
		// the common path parts
		if (out.length > 0)
			return out + to.slice(toStart + lastCommonSep);
		else {
			toStart += lastCommonSep;
			if (to.charCodeAt(toStart) === 47 /*/*/)
				++toStart;
			return to.slice(toStart);
		}
	},
	
	_makeLong: function _makeLong(path) {
		return path;
	},
	
	dirname: function dirname(path) {
		assertPath(path);
		if (path.length === 0) return '.';
		var code = path.charCodeAt(0);
		var hasRoot = code === 47 /*/*/;
		var end = -1;
		var matchedSlash = true;
		for (var i = path.length - 1; i >= 1; --i) {
			code = path.charCodeAt(i);
			if (code === 47 /*/*/) {
				if (!matchedSlash) {
					end = i;
					break;
				}
			} else {
				// We saw the first non-path separator
				matchedSlash = false;
			}
		}
		
		if (end === -1) return hasRoot ? '/' : '.';
		if (hasRoot && end === 1) return '//';
		return path.slice(0, end);
	},
	
	basename: function basename(path, ext) {
		if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
		assertPath(path);
		
		var start = 0;
		var end = -1;
		var matchedSlash = true;
		var i;
		
		if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
			if (ext.length === path.length && ext === path) return '';
			var extIdx = ext.length - 1;
			var firstNonSlashEnd = -1;
			for (i = path.length - 1; i >= 0; --i) {
				var code = path.charCodeAt(i);
				if (code === 47 /*/*/) {
					// If we reached a path separator that was not part of a set of path
					// separators at the end of the string, stop now
					if (!matchedSlash) {
						start = i + 1;
						break;
					}
				} else {
					if (firstNonSlashEnd === -1) {
						// We saw the first non-path separator, remember this index in case
						// we need it if the extension ends up not matching
						matchedSlash = false;
						firstNonSlashEnd = i + 1;
					}
					if (extIdx >= 0) {
						// Try to match the explicit extension
						if (code === ext.charCodeAt(extIdx)) {
							if (--extIdx === -1) {
								// We matched the extension, so mark this as the end of our path
								// component
								end = i;
							}
						} else {
							// Extension does not match, so our result is the entire path
							// component
							extIdx = -1;
							end = firstNonSlashEnd;
						}
					}
				}
			}
			
			if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
			return path.slice(start, end);
		} else {
			for (i = path.length - 1; i >= 0; --i) {
				if (path.charCodeAt(i) === 47 /*/*/) {
					// If we reached a path separator that was not part of a set of path
					// separators at the end of the string, stop now
					if (!matchedSlash) {
						start = i + 1;
						break;
					}
				} else if (end === -1) {
					// We saw the first non-path separator, mark this as the end of our
					// path component
					matchedSlash = false;
					end = i + 1;
				}
			}
			
			if (end === -1) return '';
			return path.slice(start, end);
		}
	},
	
	extname: function extname(path) {
		assertPath(path);
		var startDot = -1;
		var startPart = 0;
		var end = -1;
		var matchedSlash = true;
		// Track the state of characters (if any) we see before our first dot and
		// after any path separator we find
		var preDotState = 0;
		for (var i = path.length - 1; i >= 0; --i) {
			var code = path.charCodeAt(i);
			if (code === 47 /*/*/) {
				// If we reached a path separator that was not part of a set of path
				// separators at the end of the string, stop now
				if (!matchedSlash) {
					startPart = i + 1;
					break;
				}
				continue;
			}
			if (end === -1) {
				// We saw the first non-path separator, mark this as the end of our
				// extension
				matchedSlash = false;
				end = i + 1;
			}
			if (code === 46 /*.*/) {
				// If this is our first dot, mark it as the start of our extension
				if (startDot === -1)
					startDot = i;
				else if (preDotState !== 1)
					preDotState = 1;
			} else if (startDot !== -1) {
				// We saw a non-dot and non-path separator before our dot, so we should
				// have a good chance at having a non-empty extension
				preDotState = -1;
			}
		}
		
		if (startDot === -1 || end === -1 ||
			// We saw a non-dot character immediately before the dot
			preDotState === 0 ||
			// The (right-most) trimmed path component is exactly '..'
			preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
			return '';
		}
		return path.slice(startDot, end);
	},

	ext2name: function ext2name(path) {
		assertPath(path);
		let pos;
		pos=path.lastIndexOf("/");
		if(pos>=0){
			path=path.substring(pos+1);
		}
		pos=path.lastIndexOf(".");
		if(pos<=0){
			return "";
		}
		pos=path.lastIndexOf(".",pos-1);
		if(pos<0){
			return "";
		}
		return path.substring(pos);
	},

	format: function format(pathObject) {
		if (pathObject === null || typeof pathObject !== 'object') {
			throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
		}
		return _format('/', pathObject);
	},
	
	parse: function parse(path) {
		assertPath(path);
		
		var ret = { root: '', dir: '', base: '', ext: '', name: '' };
		if (path.length === 0) return ret;
		var code = path.charCodeAt(0);
		var isAbsolute = code === 47 /*/*/;
		var start;
		if (isAbsolute) {
			ret.root = '/';
			start = 1;
		} else {
			start = 0;
		}
		var startDot = -1;
		var startPart = 0;
		var end = -1;
		var matchedSlash = true;
		var i = path.length - 1;
		
		// Track the state of characters (if any) we see before our first dot and
		// after any path separator we find
		var preDotState = 0;
		
		// Get non-dir info
		for (; i >= start; --i) {
			code = path.charCodeAt(i);
			if (code === 47 /*/*/) {
				// If we reached a path separator that was not part of a set of path
				// separators at the end of the string, stop now
				if (!matchedSlash) {
					startPart = i + 1;
					break;
				}
				continue;
			}
			if (end === -1) {
				// We saw the first non-path separator, mark this as the end of our
				// extension
				matchedSlash = false;
				end = i + 1;
			}
			if (code === 46 /*.*/) {
				// If this is our first dot, mark it as the start of our extension
				if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
			} else if (startDot !== -1) {
				// We saw a non-dot and non-path separator before our dot, so we should
				// have a good chance at having a non-empty extension
				preDotState = -1;
			}
		}
		
		if (startDot === -1 || end === -1 ||
			// We saw a non-dot character immediately before the dot
			preDotState === 0 ||
			// The (right-most) trimmed path component is exactly '..'
			preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
			if (end !== -1) {
				if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
			}
		} else {
			if (startPart === 0 && isAbsolute) {
				ret.name = path.slice(1, startDot);
				ret.base = path.slice(1, end);
			} else {
				ret.name = path.slice(startPart, startDot);
				ret.base = path.slice(startPart, end);
			}
			ret.ext = path.slice(startDot, end);
		}
		
		if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
		
		return ret;
	},
	
	sep: '/',
	delimiter: ':',
	win32: null,
	posix: null
};

posix.posix = posix;

module$3.exports = posix;

//>>>>>>Node2Coke>>>>>>
var pathLib = module$1$1.exports;
//<<<<<<Node2Coke<<<<<<

//>>>>>>Node2Coke>>>>>>
var module$1={exports:{}};
var module$2=module$1;

var R$1 = typeof Reflect === 'object' ? Reflect : null;
var ReflectApply = R$1 && typeof R$1.apply === 'function'
	? R$1.apply
	: function ReflectApply(target, receiver, args) {
		return Function.prototype.apply.call(target, receiver, args);
	};

var ReflectOwnKeys;
if (R$1 && typeof R$1.ownKeys === 'function') {
	ReflectOwnKeys = R$1.ownKeys;
} else if (Object.getOwnPropertySymbols) {
	ReflectOwnKeys = function ReflectOwnKeys(target) {
		return Object.getOwnPropertyNames(target)
			.concat(Object.getOwnPropertySymbols(target));
	};
} else {
	ReflectOwnKeys = function ReflectOwnKeys(target) {
		return Object.getOwnPropertyNames(target);
	};
}

function ProcessEmitWarning(warning) {
	if (console && console.warn) console.warn(warning);
}

var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
	return value !== value;
};

function EventEmitter() {
	EventEmitter.init.call(this);
}
module$2.exports = EventEmitter;
module$2.exports.once = once;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;

function checkListener(listener) {
	if (typeof listener !== 'function') {
		throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
	}
}

Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
	enumerable: true,
	get: function() {
		return defaultMaxListeners;
	},
	set: function(arg) {
		if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
			throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
		}
		defaultMaxListeners = arg;
	}
});

EventEmitter.init = function() {
	
	if (this._events === undefined ||
		this._events === Object.getPrototypeOf(this)._events) {
		this._events = Object.create(null);
		this._eventsCount = 0;
	}
	
	this._maxListeners = this._maxListeners || undefined;
};

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
	if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
		throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
	}
	this._maxListeners = n;
	return this;
};

function _getMaxListeners(that) {
	if (that._maxListeners === undefined)
		return EventEmitter.defaultMaxListeners;
	return that._maxListeners;
}

EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
	return _getMaxListeners(this);
};

EventEmitter.prototype.emit = function emit(type) {
	var args = [];
	for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
	var doError = (type === 'error');
	
	var events = this._events;
	if (events !== undefined)
		doError = (doError && events.error === undefined);
	else if (!doError)
		return false;
	
	// If there is no 'error' event listener then throw.
	if (doError) {
		var er;
		if (args.length > 0)
			er = args[0];
		if (er instanceof Error) {
			// Note: The comments on the `throw` lines are intentional, they show
			// up in Node's output if this results in an unhandled exception.
			throw er; // Unhandled 'error' event
		}
		// At least give some kind of context to the user
		var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
		err.context = er;
		throw err; // Unhandled 'error' event
	}
	
	var handler = events[type];
	
	if (handler === undefined)
		return false;
	
	if (typeof handler === 'function') {
		ReflectApply(handler, this, args);
	} else {
		var len = handler.length;
		var listeners = arrayClone(handler, len);
		for (var i = 0; i < len; ++i)
			ReflectApply(listeners[i], this, args);
	}
	
	return true;
};

function _addListener(target, type, listener, prepend) {
	var m;
	var events;
	var existing;
	
	checkListener(listener);
	
	events = target._events;
	if (events === undefined) {
		events = target._events = Object.create(null);
		target._eventsCount = 0;
	} else {
		// To avoid recursion in the case that type === "newListener"! Before
		// adding it to the listeners, first emit "newListener".
		if (events.newListener !== undefined) {
			target.emit('newListener', type,
				listener.listener ? listener.listener : listener);
			
			// Re-assign `events` because a newListener handler could have caused the
			// this._events to be assigned to a new object
			events = target._events;
		}
		existing = events[type];
	}
	
	if (existing === undefined) {
		// Optimize the case of one listener. Don't need the extra array object.
		existing = events[type] = listener;
		++target._eventsCount;
	} else {
		if (typeof existing === 'function') {
			// Adding the second element, need to change to array.
			existing = events[type] =
				prepend ? [listener, existing] : [existing, listener];
			// If we've already got an array, just append.
		} else if (prepend) {
			existing.unshift(listener);
		} else {
			existing.push(listener);
		}
		
		// Check for listener leak
		m = _getMaxListeners(target);
		if (m > 0 && existing.length > m && !existing.warned) {
			existing.warned = true;
			// No error code for this since it is a Warning
			// eslint-disable-next-line no-restricted-syntax
			var w = new Error('Possible EventEmitter memory leak detected. ' +
				existing.length + ' ' + String(type) + ' listeners ' +
				'added. Use emitter.setMaxListeners() to ' +
				'increase limit');
			w.name = 'MaxListenersExceededWarning';
			w.emitter = target;
			w.type = type;
			w.count = existing.length;
			ProcessEmitWarning(w);
		}
	}
	
	return target;
}

EventEmitter.prototype.addListener = function addListener(type, listener) {
	return _addListener(this, type, listener, false);
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.prependListener =
	function prependListener(type, listener) {
		return _addListener(this, type, listener, true);
	};

function onceWrapper() {
	if (!this.fired) {
		this.target.removeListener(this.type, this.wrapFn);
		this.fired = true;
		if (arguments.length === 0)
			return this.listener.call(this.target);
		return this.listener.apply(this.target, arguments);
	}
}

function _onceWrap(target, type, listener) {
	var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
	var wrapped = onceWrapper.bind(state);
	wrapped.listener = listener;
	state.wrapFn = wrapped;
	return wrapped;
}

EventEmitter.prototype.once = function once(type, listener) {
	checkListener(listener);
	this.on(type, _onceWrap(this, type, listener));
	return this;
};

EventEmitter.prototype.prependOnceListener =
	function prependOnceListener(type, listener) {
		checkListener(listener);
		this.prependListener(type, _onceWrap(this, type, listener));
		return this;
	};

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
	function removeListener(type, listener) {
		var list, events, position, i, originalListener;
		
		checkListener(listener);
		
		events = this._events;
		if (events === undefined)
			return this;
		
		list = events[type];
		if (list === undefined)
			return this;
		
		if (list === listener || list.listener === listener) {
			if (--this._eventsCount === 0)
				this._events = Object.create(null);
			else {
				delete events[type];
				if (events.removeListener)
					this.emit('removeListener', type, list.listener || listener);
			}
		} else if (typeof list !== 'function') {
			position = -1;
			
			for (i = list.length - 1; i >= 0; i--) {
				if (list[i] === listener || list[i].listener === listener) {
					originalListener = list[i].listener;
					position = i;
					break;
				}
			}
			
			if (position < 0)
				return this;
			
			if (position === 0)
				list.shift();
			else {
				spliceOne(list, position);
			}
			
			if (list.length === 1)
				events[type] = list[0];
			
			if (events.removeListener !== undefined)
				this.emit('removeListener', type, originalListener || listener);
		}
		
		return this;
	};

EventEmitter.prototype.off = EventEmitter.prototype.removeListener;

EventEmitter.prototype.removeAllListeners =
	function removeAllListeners(type) {
		var listeners, events, i;
		
		events = this._events;
		if (events === undefined)
			return this;
		
		// not listening for removeListener, no need to emit
		if (events.removeListener === undefined) {
			if (arguments.length === 0) {
				this._events = Object.create(null);
				this._eventsCount = 0;
			} else if (events[type] !== undefined) {
				if (--this._eventsCount === 0)
					this._events = Object.create(null);
				else
					delete events[type];
			}
			return this;
		}
		
		// emit removeListener for all listeners on all events
		if (arguments.length === 0) {
			var keys = Object.keys(events);
			var key;
			for (i = 0; i < keys.length; ++i) {
				key = keys[i];
				if (key === 'removeListener') continue;
				this.removeAllListeners(key);
			}
			this.removeAllListeners('removeListener');
			this._events = Object.create(null);
			this._eventsCount = 0;
			return this;
		}
		
		listeners = events[type];
		
		if (typeof listeners === 'function') {
			this.removeListener(type, listeners);
		} else if (listeners !== undefined) {
			// LIFO order
			for (i = listeners.length - 1; i >= 0; i--) {
				this.removeListener(type, listeners[i]);
			}
		}
		
		return this;
	};

function _listeners(target, type, unwrap) {
	var events = target._events;
	
	if (events === undefined)
		return [];
	
	var evlistener = events[type];
	if (evlistener === undefined)
		return [];
	
	if (typeof evlistener === 'function')
		return unwrap ? [evlistener.listener || evlistener] : [evlistener];
	
	return unwrap ?
		unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}

EventEmitter.prototype.listeners = function listeners(type) {
	return _listeners(this, type, true);
};

EventEmitter.prototype.rawListeners = function rawListeners(type) {
	return _listeners(this, type, false);
};

EventEmitter.listenerCount = function(emitter, type) {
	if (typeof emitter.listenerCount === 'function') {
		return emitter.listenerCount(type);
	} else {
		return listenerCount.call(emitter, type);
	}
};

EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
	var events = this._events;
	
	if (events !== undefined) {
		var evlistener = events[type];
		
		if (typeof evlistener === 'function') {
			return 1;
		} else if (evlistener !== undefined) {
			return evlistener.length;
		}
	}
	
	return 0;
}

EventEmitter.prototype.eventNames = function eventNames() {
	return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};

function arrayClone(arr, n) {
	var copy = new Array(n);
	for (var i = 0; i < n; ++i)
		copy[i] = arr[i];
	return copy;
}

function spliceOne(list, index) {
	for (; index + 1 < list.length; index++)
		list[index] = list[index + 1];
	list.pop();
}

function unwrapListeners(arr) {
	var ret = new Array(arr.length);
	for (var i = 0; i < ret.length; ++i) {
		ret[i] = arr[i].listener || arr[i];
	}
	return ret;
}

function once(emitter, name) {
	return new Promise(function (resolve, reject) {
		function errorListener(err) {
			emitter.removeListener(name, resolver);
			reject(err);
		}
		
		function resolver() {
			if (typeof emitter.removeListener === 'function') {
				emitter.removeListener('error', errorListener);
			}
			resolve([].slice.call(arguments));
		}		
		eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
		if (name !== 'error') {
			addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
		}
	});
}

function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
	if (typeof emitter.on === 'function') {
		eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
	}
}

function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
	if (typeof emitter.on === 'function') {
		if (flags.once) {
			emitter.once(name, listener);
		} else {
			emitter.on(name, listener);
		}
	} else if (typeof emitter.addEventListener === 'function') {
		// EventTarget does not have `error` event semantics like Node
		// EventEmitters, we do not listen for `error` events here.
		emitter.addEventListener(name, function wrapListener(arg) {
			// IE does not have builtin `{ once: true }` support so we
			// have to do it manually.
			if (flags.once) {
				emitter.removeEventListener(name, wrapListener);
			}
			listener(arg);
		});
	} else {
		throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
	}
}

//**********************************************************************************************************************
//Make a object emitter
//**********************************************************************************************************************
var makeObjEventEmitter;
{
	let emitDeep=0;
	makeObjEventEmitter=function(obj){
		let events={};
		let mute=0;
		if(obj.emit){
			return;
		}
		obj.on=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			callback._call_once=false;
			if(!cbkSet){
				events[msg]=cbkSet=new Set();
				cbkSet.mute=0;
			}
			cbkSet.add(callback);
		};
		obj.once=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			callback._call_once=true;
			if(!cbkSet){
				events[msg]=cbkSet=new Set();
				cbkSet.mute=0;
			}
			cbkSet.add(callback);
		};
		obj.off=function(msg,callback){
			let cbkSet;
			cbkSet=events[msg];
			if(cbkSet){
				cbkSet.delete(callback);
			}
		};
		obj.muteEmit=function(msg){
			if(!msg) {
				mute += 1;
			}else {
				let cbkSet;
				cbkSet=events[msg];
				if(!cbkSet){
					events[msg]=cbkSet=new Set();
					cbkSet.mute=0;
				}
				cbkSet.mute+=1;
			}
		};
		obj.unmuteEmit=function(msg){
			if(!msg) {
				mute -= 1;
			}else {
				let cbkSet;
				cbkSet=events[msg];
				if(cbkSet){
					cbkSet.mute+=1;
				}
			}
		};
		obj.emit=function(msg,...args){
			let cbkSet,cbks,cbk;
			if(mute)
				return;
			cbkSet=events[msg];
			emitDeep++;
			if(emitDeep>20){
				console.warn("Emit too deep, no more emits");
				emitDeep--;
				return;
			}
			if(cbkSet){
				if(!cbkSet.mute) {
					cbks = Array.from(cbkSet.keys());
					for (cbk of cbks) {
						cbk(...args);
						if (cbk._call_once) {
							cbkSet.delete(cbk);
						}
					}
				}
			}
			emitDeep--;
		};
		obj.eventNames=function(){
			return Object.keys(events);
		};
		obj.removeAllListeners=function(eventName){
			if(eventName){
				let cbkSet;
				cbkSet=events[eventName];
				if(cbkSet){
					cbkSet.clear();
				}
			}else {
				events={};
			}
		};
	};
}

//***************************************************************************
//callAtfer function:
//***************************************************************************
let callAfter;
{
	let aboutCall=0;
	let callList=[];
	let makeCall=function(){
		let list,i,n;
		list=callList;
		aboutCall=0;
		callList=[];
		n=list.length;
		for(i=0;i<n;i++){
			list[i]();
		}
	};
	callAfter=async function(func,timeout){
		let pms;
		if(!timeout){
			callList.push(func);
			if(aboutCall){
				return;
			}
			aboutCall=1;
			pms=new Promise((resolve,reject)=>{
				resolve();
			});
			await pms;
			makeCall();
			return;
		}
		window.setTimeout(func,timeout);
	};
}

//***************************************************************************
//Notify-Object
//***************************************************************************
let makeNotify;
{
	makeNotify=function(self){
		let m_NotifyPaused;
		let m_viewHubIn = {};
		let m_viewHubOn = {};
		let m_isInEnvList = 0;
		let m_NotifyOnMsgHash = {};
		let m_PendingNofifyOn=[];
		let m_msgValHash={};
		let removeValBindOfView;
		let notifyToMap,notifyHubOn,notifyOnAll;
		let muteNotify=false;
		if(self.emitNotify){
			return;
		}
		//---------------------------------------------------------------
		//make a property val notify-able, fires notify when this property changes:
		self.upgradeVal = function (name, msg) {
			var oldMsg, curVal, desc, oldGet, oldSet,msgList;
			if (!(name in self)) {
				return;
			}
			if (!msg) {
				msg = "*";//default notify message is "*"
			}
			if(Array.isArray(msg)){
				msgList=msg;
			}
			oldMsg = m_msgValHash[name];
			if (oldMsg) {
				if (msg !== oldMsg) {
					throw "JAXDataObj upgradVal error: val " + name + " is already been upgraded with diffrent msg " + oldMsg + ", new msg: " + msg;
				}
				return;
			}
			desc = Object.getOwnPropertyDescriptor(self, name);
			oldGet = desc.get;
			oldSet = desc.set;
			curVal = self[name];
			m_msgValHash[name] = msg;
			if(msgList){
				//Mapping:
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							let msg;
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							for(msg of msgList) {
								//notifyHubIn(msg);//这个要去掉
								notifyHubOn(msg);
							}
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}else {
				//Mapping:
				Object.defineProperty(self, name,
					{
						enumerable: desc.enumerable,
						configurable: true,
						set: function (newVal) {
							curVal = newVal;
							if (oldSet) {
								oldSet.call(self, newVal);
							}
							notifyHubOn(msg);
							return newVal;
						},
						get: function () {
							return oldGet ? oldGet.call(self) : curVal;
						}
					}
				);
			}
		};
		
		//---------------------------------------------------------------
		//Get a "upgraded" property val's notify message string:
		self.getValMsg = function (name) {
			return m_msgValHash[name];
		};
		
		//---------------------------------------------------------------
		//Install a message tracer:
		self.onNotify=self.bindValNotify = function (msgName,func,view,once=0) {
			var map, set, msg;
			if (!func) {
				console.error("hub notify function!!");
				return;
			}
			if (!(msgName in self)) {
				msg=msgName;
			}else {
				msg = m_msgValHash[msgName];
			}
			if(!msg){
				throw ""+msgName+" is not upgraded!";
			}
			map = m_viewHubOn[msg];
			if (!map) {
				map = m_viewHubOn[msg] = new Map();
				map.mute=0;
			}
			set = map.get(view);
			if (!set) {
				set = new Set();
				map.set(view, set);
			}
			if(!once) {
				set.add(func);
			}else {
				let onceFunc;
				onceFunc=function(...args){
					func(...args);
					self.off(msg,onceFunc,view);
				};
				set.add(onceFunc);
			}
			return msg;
		};
		
		//---------------------------------------------------------------
		//Install an one-time message tracer
		self.onceNotify=function(msgName,func,view){
			self.onNotify(msgName,func,view,1);
		};
		
		//---------------------------------------------------------------
		//Uninstall all message tracers of a view
		self.removeValBindOfView = removeValBindOfView = function (msgName, view) {
			var list, i;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				list = m_viewHubOn;
				for (i in list) {
					removeValBindOfView(i, view);
				}
				return;
			}
			list = m_viewHubIn[msgName];
			if (list) {
				list.delete(view);
			}
			list = m_viewHubOn[msgName];
			if (list) {
				list.delete(view);
			}
		};
		
		//---------------------------------------------------------------
		//Uninstall a message tracer:
		self.offNotify=self.removeValNotify = function (msgName, func, view) {
			var list, map, set, i, msg;
			if (!msgName) {
				list = m_viewHubIn;
				for (i in list) {
					msg=i;
					self.removeValNotify(msg, view, func);
				}
				list = m_viewHubOn;
				for (i in list) {
					msg=i;
					self.removeValNotify(i, view, func);
				}
				return;
			}
			map = m_viewHubIn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
			map = m_viewHubOn[msgName];
			if (map) {
				set = map.get(view);
				if (set) {
					set.delete(func);
				}
			}
		};
		
		//---------------------------------------------------------------
		notifyToMap = function (map) {
			var views, view, set, func;
			views = map.keys();
			for (view of views) {
				if (!view || view.allowValNotify!==false) {
					set = map.get(view);
					for (func of set) {
						func();
					}
				}
			}
		};
		
		//---------------------------------------------------------------
		//Set to fire a message notify, 
		self.emitNotify=self.notifyValMsgOn = notifyHubOn = function (msg) {
			if(!m_NotifyOnMsgHash[msg] && !muteNotify) {
				let map = m_viewHubOn[msg];
				if(map && map.mute){
					return;
				}
				
				m_NotifyOnMsgHash[msg] = 1;
				m_PendingNofifyOn.push(msg);
				if (m_isInEnvList)
					return;
				m_isInEnvList = 1;
				callAfter(notifyOnAll);
			}
		};
		
		//---------------------------------------------------------------
		//Fire all panding messages:
		notifyOnAll = function () {
			var map, msg, list, loop;
			m_isInEnvList = 0;
			if (m_NotifyPaused) {
				return;
			}
			loop = 0;
			do {
				list = m_PendingNofifyOn.splice(0);
				for (msg of list) {
					m_NotifyOnMsgHash[msg] = 0;
					map = m_viewHubOn[msg];
					if (map) {
						notifyToMap(map);
					}
				}
				loop++;
				if (loop > 3) {
					console.warn(`JAXDataObj notify too many times.`);
					break;
				}
			} while (m_PendingNofifyOn.length);
		};
		
		//---------------------------------------------------------------
		Object.defineProperty(self,"pauseValNotify",{
			get:function(){
				return m_NotifyPaused;
			},
			set:function(v){
				v=v?1:0;
				m_NotifyPaused=v;
				return v;
			}
		});
		
		//-------------------------------------------------------------------
		self.muteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (!map) {
					map = m_viewHubOn[msg] = new Map();
					map.mute=1;
				}
			}else {
				muteNotify++;
			}
		};
		
		//-------------------------------------------------------------------
		self.unmuteNotify=function(msg){
			if(msg){
				let map;
				map = m_viewHubOn[msg];
				if (map) {
					map.mute-=1;
				}
			}else {
				muteNotify--;
			}
		};
	};
}
module$1.exports['once'];
//<<<<<<Node2Coke<<<<<<

//****************************************************************************
//:Parse URL params:
//****************************************************************************
{
	let pos;
	let appURL=document.location.href;
	let appParams={};
	VFACT.appParams=appParams;
	VFACT.appURL=document.location.href;
	VFACT.appEntry=document.location.pathname;
	VFACT.appPath=pathLib.dirname(document.location.pathname);
	VFACT.appOrigin=document.location.origin;
	pos=appURL.indexOf("?");
	if(pos<0){
		pos=appURL.indexOf("#");
	}
	if(pos>0){
		let ptext,list;
		ptext=appURL.substring(pos+1);
		list=ptext.split("&");
		list.forEach(item=>{
			let subs,key,val;
			subs=item.split("=");
			if(subs.length===2){
				key=decodeURIComponent(subs[0]);
				val=decodeURIComponent(subs[1]);
				appParams[key]=val;
			}
		});
	}
	if(VFACT.appEntry.startsWith("//")){
		VFACT.appFilePath=VFACT.appEntry.substring(1);
	}else if(VFACT.appEntry.startsWith("/~/")){
		VFACT.appFilePath=VFACT.appEntry.substring(2);
	}else {
		VFACT.appFilePath=VFACT.appEntry;
	}
	if(VFACT.appFilePath){
		VFACT.appDirFilePath=pathLib.dirname(VFACT.appFilePath);
	}else {
		VFACT.appDirFilePath="";
	}
}

//****************************************************************************
//:Load CSS/Scripts:
//****************************************************************************
{
	let dynaScripts={};
	//--------------------------------------------------------------------
	VFACT.appendCSS=function(path){
		let pms=dynaScripts[path];
		if(pms){
			return pms;
		}
		pms=new Promise((resolve,reject)=>{
			let tag;
			tag=document.createElement('link');
			tag.rel="stylesheet";
			tag.href = document.location.origin+path;
			tag.type="text/css";
			document.getElementsByTagName('head')[0].appendChild(tag);
			//document.body.appendChild(tag);
			resolve();
		});
		dynaScripts[path]=pms;
		return pms;
	};

	//--------------------------------------------------------------------
	VFACT.appendScript=function(path){
		let pms=dynaScripts[path];
		if(pms){
			return pms;
		}
		pms=new Promise((resolve,reject)=>{
			let tag;
			tag=document.createElement('script');
			tag.onload = function () {
				resolve();
			};
			tag.onerror = function () {
				reject();
			};
			tag.src = document.location.origin+path;
			document.body.appendChild(tag);
		});
		dynaScripts[path]=pms;
		return pms;
	};
}

//****************************************************************************
//:Download dummy obj:
//****************************************************************************
{
	let webFileDownload;
	webFileDownload=document.createElement("a");
	webFileDownload.style.position="absolute";
	webFileDownload.style.top="-300px";
	webFileDownload.style.opacity="0";
	document.body.appendChild(webFileDownload);
	VFACT.webFileDownload=webFileDownload;
}

//****************************************************************************
//:CreateApp UI by uiDef and opts:
//****************************************************************************
function fixColor(v){
	let l;
	if(Array.isArray(v)){
		v=[...v];
		if(v.length>=5){
			l=v[4];
			if(l>=0){
				l=l>100?100:l;
				v[0]=(255-v[0])*l/100+v[0];
				v[1]=(255-v[1])*l/100+v[1];
				v[2]=(255-v[2])*l/100+v[2];
			}else if(l<0){
				l=l<-100?-100:l;
				v[0]=v[0]*(100+l)/100;
				v[1]=v[1]*(100+l)/100;
				v[2]=v[2]*(100+l)/100;
			}
		}else if(v.length<4){
			v[3]=1;
		}
		return `rgba(${v})`;
	}
	return v;
}

let createApp=async function(){
	let body,appObj,appDef,path,pos;
	appDef={
		type:"obj",id:"FACTAppFrame",x:0,y:0,w:"100%",h:"100%",nameHost:1,traceSize:1,
	};
	body=document.body;
	appObj=VFACT.createObj(appDef,body);
	if(!VFACT.app){
		VFACT.app=appObj;
		let appCfg=null;
		appCfg=VFACT.appCfg;
		if(appCfg){
			if(appCfg.color){
				let bgColor=appCfg.color.body;
				if(bgColor){
					body.style.background=fixColor(bgColor);
				}
			}
		}
	}
	VFACT.makeNotify(appObj);
	//app basic info:
	appObj.appParams=VFACT.appParams;
	path=document.location.pathname;
	appObj.appPath=path;
	pos=path.lastIndexOf("/");
	appObj.appDir=path.substring(0,pos);
	appObj.appURL=VFACT.appURL;
	appObj.appOrigin=VFACT.appOrigin;
	appObj.appFilePath=VFACT.appFilePath;
	appObj.path2AppFilePath=function(path){
		return pathLib.join(VFACT.appDirFilePath,path);
	};
	appObj.path2AppURL=function(path){
		let appDir;
		if(path[0]==="/"){
			return VFACT.appOrigin+path;
		}
		appDir=VFACT.appPath;
		if(appDir.startsWith("//")){
			return VFACT.appOrigin+"/~"+pathLib.join(appDir,path);
		}
		return VFACT.appOrigin+pathLib.join(appDir,path);
	};
	makeObjEventEmitter(appObj);
	makeNotify(appObj);
	return appObj;
};

//----------------------------------------------------------------------------
//Init the app by major-UIDef and options, based on options setup Dialog, tip, 
//shortcuts and other basic features of App:
let initApp=async function(appObj,uiDef,opts={}){
	let uiDefs,appFrame;
	let dlgLayer;

	//setup default options:
	if(!("dialog" in opts)){
		opts.dialog=1;
	}

	if(!("tip" in opts)){
		opts.tip=1;
	}
	appFrame=appObj.appFrame=opts.appFrame||null;
	
	if(appFrame && appFrame.appParams){
		VFACT.appParams=appFrame.appParams;
	}

	if(Array.isArray(uiDef)){
		uiDefs=uiDef;
	}else {
		uiDefs=[uiDef||{
			type:"obj",id:"MainUILayer",x:0,y:0,w:"100%",h:"100%",
		}];
	}

	appObj.OnAppCreate=function(){
		this.children[0];
		dlgLayer=this.DlgLayer;
	};

	//************************************************************************
	//Enable dialog feature?
	//************************************************************************
	let isShowDlg=0;
	let dlgList=[];
	if(opts.dialog){
		uiDefs.push({
			type:"box",id:"DlgLayer",x:0,y:0,w:"100%",h:"100%",zIndex:200,display:0,
			OnClick:function(evt){
				appObj.OnDlgBGClick(evt);
			}
		});
		//--------------------------------------------------------------------
		appObj.getDlg=function(){
			let idx=dlgList.length-1;
			return dlgList[idx];
		};
		
		//--------------------------------------------------------------------
		let dlgHash={};
		async function loadDlg(url){
			if(dlgHash[url]){
				return dlgHash[url];
			}
			try{
				if(!url.startsWith("/")){
					url=appObj.path2AppURL(url);
				}
				dlgHash[url]=(await import(url)).default;
			}catch(err){
				console.error(err);
				return null;
			}
			return dlgHash[url];
		}
		
		//--------------------------------------------------------------------
		//Show dialog:
		appObj.showDlg=function(dlgFunc,vo,shared=1,callback=null){
			var dlgHud,dlgCSS,curDlg,checkBG;
			
			if(typeof(dlgFunc)==="string"){
				loadDlg(dlgFunc).then((func)=>{
					appObj.showDlg(func,vo,shared,callback);
				});
				return null;
			}
			if(!dlgFunc)
				return null;	
			//Show dialog BG:
			if(!isShowDlg) {
				dlgLayer.display=1;
				isShowDlg = 1;
				checkBG=1;
			}
			//If there is a dialog, make it mute to user input. New dialog will be on top of it:
			curDlg=dlgList.length>0?dlgList[dlgList.length-1]:null;
			if(curDlg){
				curDlg.uiEvent=-1;
			}
	
			if(dlgFunc.$_pptMap){//If dialog is already a vfact-ui-obj, make sure it can append to dlg-layer:
				dlgHud=dlgFunc;
				if(dlgHud.parent){
					dlgHud.hold();
					dlgHud.parent.removeChild(dlgHud);
				}
				dlgHud.display=true;
				dlgLayer.appendChild(dlgHud);
			}else if(shared){//If dialog is sharing instance, try use shared instance:
				shared=""+shared;
				if(!dlgFunc.sharedDlgs){
					dlgFunc.sharedDlgs={};
				}
				dlgHud=dlgFunc.sharedDlgs[shared];
				if(!dlgHud) {
					dlgCSS = dlgFunc(appObj);
					dlgHud = dlgLayer.appendNewChild(dlgCSS);
					dlgFunc.sharedDlgs[shared]= dlgHud;
					dlgHud.hold();
				}else {
					dlgLayer.appendChild(dlgHud);
				}
			}else {
				dlgCSS = dlgFunc(appObj);
				dlgHud = dlgLayer.appendNewChild(dlgCSS);
			}
			if(checkBG) {
				if (dlgHud.showDlgBGMask) {
					dlgLayer.color = [0, 0, 0, 0.5];
				} else {
					dlgLayer.color = [0, 0, 0, 0];
				}
			}
			dlgHud.uiEvent=1;
			dlgHud.showDlg && dlgHud.showDlg(vo);
			dlgList.push(dlgHud);
			dlgHud._dlgCallback=callback;
			return dlgHud;
		};
		
		//--------------------------------------------------------------------
		appObj.modalDlg=function(dlgFunc,vo,shared=1){
			return new Promise((resolve)=>{
				this.showDlg(dlgFunc,vo,shared,resolve);
			});
		};
	
		//--------------------------------------------------------------------
		//Close dialog:
		appObj.closeDlg=function(dlg,result){
			var idx,preDlg;
			if(!dlg){
				idx=dlgList.length-1;
				dlg=dlgList[idx];
			}else {
				idx=dlgList.indexOf(dlg);
			}
			if(idx<0){
				//The dialog is hiding
				return;
			}
			dlg.closeDlg && dlg.closeDlg(result);
			dlgLayer.removeChild(dlg);
			if(idx===dlgList.length-1){
				//This is the last one:
				preDlg=dlgList[idx-1];
				if(preDlg){
					preDlg.uiEvent=1;
				}
			}
			dlgList.splice(idx,1);
			//If no more dialog is showing, close dialog BG and layer:
			if(dlgList.length===0){
				dlgLayer.display=0;
				isShowDlg=0;
			}
			if(dlg._dlgCallback){
				dlg._dlgCallback(result);
				dlg._dlgCallback=null;
			}
		};
	
		//--------------------------------------------------------------------
		//Dialog BG been clicked:
		appObj.OnDlgBGClick=function(){
			let idx,dlg;
			idx=dlgList.length-1;
			dlg=dlgList[idx];
			if(dlg && dlg.OnBGClick){
				dlg.OnBGClick();
			}
		};
		
		//--------------------------------------------------------------------
		//Make an existing hud-item as an dialog:
		appObj.showFloatDlg=function(hud,bgColor){
			let curDlg;
			//Show dialog BG:
			if(!isShowDlg) {
				dlgLayer.display=1;
				isShowDlg = 1;
				dlgLayer.color = bgColor||[0, 0, 0, 0];
			}else {
				curDlg=dlgList.length>0?dlgList[dlgList.length-1]:null;
				if(curDlg){
					curDlg.uiEvent=-1;
				}
			}
			hud._orgZIndex=hud.zIndex;
			hud.zIndex=dlgLayer.zIndex+10;
			dlgList.push(hud);
		};
		
		//--------------------------------------------------------------------
		//Close a float-dialog:
		appObj.closeFloatDlg=function(dlg){
			var idx,preDlg;
			if(!dlg){
				idx=dlgList.length-1;
				dlg=dlgList[idx];
			}else {
				idx=dlgList.indexOf(dlg);
			}
			if(idx<0){
				//The dialog is hiding?
				if(dlgList.length===0){
					dlgLayer.display=0;
					isShowDlg=0;
				}
				return;
			}
			dlg.zIndex=dlg._orgZIndex;
			if(idx===dlgList.length-1){
				//This is the last one:
				preDlg=dlgList[idx-1];
				if(preDlg){
					preDlg.uiEvent=1;
				}
			}
			dlgList.splice(idx,1);
			//If no more dialog is showing, close dialog BG and layer:
			if(dlgList.length===0){
				dlgLayer.display=0;
				isShowDlg=0;
			}
		};
	}else {
		appObj.showDlg=function(){
			return null;
		};
	}
	
	//************************************************************************
	//Enable wait dialog featre
	//************************************************************************
	if(opts.dialog && opts.wait){
		let waitDlgDef,waitDlg,isShowWait;
		waitDlgDef=function(app){
			return {
				type:"box",id:"WaitDlg",x:0,y:0,w:"FW",h:"FH",background:[0,0,0,0.3],autoLayout:1,nameHost:1,
				children:[
					{
						type:"box",id:"BoxInfo",x:"FW/2",y:"FH/2",w:"FW>600?FW/2:300",h:80,anchorX:1,background:"#FFFFFF",shadow:1,shadowX:3,shadowY:8,shadowBlur:5,shadowColor:[0,0,0,0.3],
						children:[
							{
								type:"text",id:"TxtInfo",x:0,y:0,w:"FW",h:"FH",color:[0,0,0,1],fontSize:15,alignX:1,alignY:1,wrap:1,
								text:"Pleas wait..."
							}
						]
					}
				],
				OnCreate(){
					waitDlg=this;
				},
				showDlg(vo){
					let time=vo.time>=0?vo.time:500;
					waitDlg.BoxInfo.display=0;
					waitDlg.TxtInfo.text=vo.info||"Please wait";
					waitDlg.background=[0,0,0,0];
					setTimeout(()=>{
						waitDlg.background=[0,0,0,0.3];
						waitDlg.BoxInfo.display=1;
					},time);
				},
			};
		};
		
		//--------------------------------------------------------------------
		appObj.showWait=function(info,time=500){
			if(isShowWait){
				waitDlg.TxtInfo=info;
				return;//
			}
			isShowWait=1;
			appObj.showDlg(waitDlgDef,{info:info,time:time});
		};
		
		//--------------------------------------------------------------------
		appObj.closeWait=function(){
			if(!isShowWait){
				return;//
			}
			isShowWait=0;
			appObj.closeDlg(waitDlg);
		};
		
		//--------------------------------------------------------------------
		appObj.isWaiting=function(){
			return isShowWait;
		};
	}
	if(opts.mask);

	//************************************************************************
	//Enable tip feature?
	//************************************************************************
	if(opts.tip){
		let cssTipBox;
		const TIP_TIME=200;
		const TIP_LIFETIME=3000;
		let isTipShowing,tgtTipHud,tipTimer;
		let tipHud=null;
		let tipBox=null;
		opts.tip=1;
		cssTipBox=function()
		{
			var txtName,text="tip";
			var tipAlignH=1,tipAlignV=0;
			return {
				nameHost:1,
				type:"box",id:"TipBox",x:0,y:0,w:200,h:20,display:0,anchorX:0,anchorY:0,
				background:[50,50,50,1],corner:3,shadow:1,shadowX:1,shadowY:3,shadowBlur:5,shadowColor:[0,0,0,0.5],
				children:[{
					type:"text",id:"TxtName",x:0,y:0,w:"FW",h:"FH",autoLayout:1,
					text:text,fontSize:12,color:[255,255,255],bold:0,
					alignH:1,alignV:1
				}],
				faces:{},
				OnCreate:function(){
					tipBox=this;
					txtName=this.TxtName;
				},
				show:function(x,y,text,alignH=1,alignV=0,time=80){
					tipAlignH=alignH;
					tipAlignV=alignV;
					tipHud.x=x;
					tipHud.y=y;
					tipHud.text=text;
					tipHud.display=1;
					//y=tipHud.y;
					//tipHud.y=y-15;
					//TODO: Support ani:
					/*tipHud.animate({
						type:"in",
						dy:-15,alpha:0,
						time:time,
					});*/
					tipHud.animate({
						type:"ani",
						keyFrames:[
							{opacity:0},
							{opacity:1},
						],
						duration:time,
					});
				},
				hide:function(){
					this.display=0;
				},
				get $text(){return text;},
				set $text(newText){
					var x,y,w,h;
					text=newText;
					if(txtName) {
						txtName.text = text;
						w=txtName.textW;
						txtName.w=w+12;
						w=tipBox.w=w+12;
						h=tipBox.h;
						switch(tipAlignH){
							case 0:
								break;
							case 1:
								tipHud.x-=w/2;
								break;
							case 2:
								tipHud.x-=w;
								break;
						}
						switch(tipAlignV){
							case 0:
								break;
							case 1:
								tipHud.y-=h/2;
								break;
							case 2:
								tipHud.y-=h;
								break;
						}
						x=tipHud.x;y=tipHud.y;
						if(x<10){
							x=tipHud.x=10;
						}
						if(x+w+10>=appObj.clientWidth){
							x=tipHud.x=appObj.clientWidth-10-w;
						}
						/*if(x+w*0.5+10>=appObj.clientWidth){
							x=tipHud.x=appObj.clientWidth-10-w*0.5;
						}*/
						if(y<10){
							y=tipHud.y=10;
						}
						if(y+h+10>=appObj.clientHeight){
							y=tipHud.y=appObj.clientHeight-10-h;
						}
					}
				}
			};
		};
		//--------------------------------------------------------------------
		//About to show tip
		appObj.showTip=function(hud,tip,x,y,ah,av,time=TIP_TIME,life=TIP_LIFETIME){
			let rect;
			let w,h,asw,ash;
			if(hud===tgtTipHud){
				return;
			}
			if(isTipShowing){
				tipHud.hide();
			}
			if(tipTimer){
				window.clearTimeout(tipTimer);
			}
			tgtTipHud=hud;
			if(!hud)
				return;
			w=hud.w;h=hud.h;
			tipTimer=window.setTimeout(()=>{
				//Show tip:
				tipTimer=null;
				if(x===undefined){
					w=hud.w;h=hud.h;
					x=w/2;y=h+5;
				}
	
				rect=hud.getBoundingClientRect();
				if(w>0){
					asw=rect.width/w;
					x*=asw;
				}
				if(h>0){
					ash=rect.height/h;
					y*=ash;
				}
				x=rect.left+x;
				y=rect.top+y;
	
				if(!tipHud){
					tipHud=tipBox;
				}
				tipHud.show(x,y,tip,ah,av);
				isTipShowing=1;
				tipTimer=window.setTimeout(()=>{
					appObj.abortTip(hud);
				},life);
			},time);
		};
	
		//--------------------------------------------------------------------
		//Cancel about-showing tip:
		appObj.abortTip=function(hud){
			if(hud && hud!==tgtTipHud){
				return;
			}
			if(tipTimer){
				window.clearTimeout(tipTimer);
				tipTimer=null;
			}
			tgtTipHud=null;
			if(isTipShowing){
				this.hideTip();
			}
		};
	
		//--------------------------------------------------------------------
		//Hide current showing tip
		appObj.hideTip=function(){
			if(isTipShowing){
				tipHud.display=0;
				isTipShowing=0;
			}
		};

		uiDefs.push({
			type:"box",id:"TipLayer",x:0,y:0,w:"100%",h:"100%",zIndex:300,uiEvent:-1,
			children:[
				cssTipBox()
			]
		});
	}
	
	//************************************************************************
	//Enable hud layer? By default it's on:
	//************************************************************************
	if(opts.hud!==false){
		uiDefs.push({
			type:"box",id:"HudLayer",x:0,y:0,w:"100%",h:"100%",zIndex:500,uiEvent:-1,
			OnCreate(){
				appObj.hudLayer=this;
			}
		});
	}
	
	//************************************************************************
	//Enable shortcuts feature?
	//************************************************************************
	if(opts.shortcuts){
		let switchApping=0;
		let switchDocing=0;
		let switchDlg=null;
		let hotBox=null;
		let DlgTask=null;

		//Check if handle task shortcut:
		if(!appFrame){
			if(opts.DlgTask){
				DlgTask=opts.DlgTask;
			}
		}
		//--------------------------------------------------------------------
		//Set focus box
		appObj.setFocusBox=function(box){
			if(box===hotBox){
				return;
			}
			if(hotBox && hotBox.OnAppBlur){
				hotBox.OnAppBlur();
			}
			hotBox=box;
			if(hotBox && hotBox.OnAppFocus){
				hotBox.OnAppFocus();
			}
			appObj.emitNotify("FocusBox");
		};
	
		//--------------------------------------------------------------------
		//Get focus box:
		appObj.getFocusBox=function(){
			return hotBox;
		};
	
		//-------------------------------------------------------------------*
		//Handle key down events:
		appObj.OnKeyDown=function(e){
			var key,list,item,i,n,hotView;
	
			if(isShowDlg){
				hotView=dlgList.length>0?dlgList[dlgList.length-1]:null;
			}else {
				hotView=hotBox;
			}
			
			function checkShortcut(item){
				if(item.altKey!==e.altKey){
					return 0;
				}
				if(item.ctrlKey!==e.ctrlKey){
					return 0;
				}
				if(item.metaKey!==e.metaKey){
					return 0;
				}
				if(item.shiftKey!==e.shiftKey){
					return 0;
				}
				return 1;
			}
			key=e.code;
			list=opts.shortcuts[key];
			if(!list){
				key=""+e.keyCode;
				list=opts.shortcuts[key];
			}
			if(hotView && hotView.OnKeyDown){
				if(hotView.OnKeyDown(e.code,e)){
					return 1;
				}
			}
			if(list) {
				if (Array.isArray(list)) {
					n = list.length;
					for (i = 0; i < n; i++) {
						item = list[i];
						if (checkShortcut(item)) {
							//Handle shortcut:
							if(hotView && hotView.handleShortcut){
								if(hotView.handleShortcut(item.action,e)){
									return 1;
								}
							}
							//Handle app shortcut here:
							if(opts.handleShortcut){
								opts.handleShortcut(item.action,e);
							}
							return 0;
						}
					}
				} else {
					item = list;
					if (checkShortcut(item)) {
						if(hotView && hotView.handleShortcut){
							if(hotView.handleShortcut(item.action,e)){
								return 1;
							}
						}
						//Handle app shortcut here:
						if(opts.handleShortcut){
							if(opts.handleShortcut(item.action,e)){
								return 1;
							}
						}
						return 0;
					}
				}
			}
	
			//Handle alt-tab switch doc:
			if(e.key==="Tab" || e.code==="Escape"){
				if(e.altKey && !e.metaKey){
					//See if we can switch doc:
					if(appFrame){
						switchDlg=appFrame.app.showTaskDlg(e);
						if(switchDlg){
							switchApping=1;
							return 1;
						}
					}else if(DlgTask){
						appObj.showTaskDlg(e);
						return 1;
					}
				}
			}
			//Check internal doc switing:
			if(opts.switchDoc && e.code==="Escape"){
				if(e.ctrlKey && !e.metaKey){
					//See if we can switch doc:
					if(switchDocing){
						if(e.shiftKey){
							opts.switchDoc.pre();
						}else {
							opts.switchDoc.next();
						}
						return 1;
					}else {
						switchDocing=1;
						opts.switchDoc.start();
						return 1;
					}
				}
			}
			return 0;
		};
	
		//-------------------------------------------------------------------
		//Handle key-up events:
		appObj.OnKeyUp=function(e){
			let hotView=null;
			if(isShowDlg){
				hotView=dlgList.length>0?dlgList[dlgList.length-1]:null;
			}else {
				hotView=hotBox;
			}
			if(hotView && hotView.OnKeyUp){
				if(hotView.OnKeyUp(e.code,e)){
					return 1;
				}
			}
			if(switchApping && e.key==="Alt"){
				if(DlgTask){
					switchDlg.gotoTask();
				}else {
					switchDlg.gotoTask();
				}
				switchApping=0;
				switchDlg=null;
				return 1;
			}
			if(switchDocing && e.key==="ctrlKey"){
				opts.switchDoc.end();
				return 1;
			}
		};
		
		//--------------------------------------------------------------------
		appObj.showTaskDlg=function(evt){
			if(switchApping){
				if(evt.shiftKey){
					switchDlg.preTask();
				}else {
					switchDlg.nextTask();
				}
				return switchDlg;
			}
			if(!isShowDlg){
				switchApping=1;
				//Show the switch doc dialog:
				switchDlg=appObj.showDlg(DlgTask,{
					byShortCut:1,
					OnClosed(){
						switchApping=0;
						switchDlg=null;
					}
				});
				return switchDlg;
			}
			return null;
		};
		document.addEventListener("keydown",(evt)=>{
			if(appObj.OnKeyDown(evt)){
				evt.stopPropagation();
				evt.preventDefault();
			}
		});
		document.addEventListener("keyup",(evt)=>{
			if(appObj.OnKeyUp(evt)){
				evt.stopPropagation();
				evt.preventDefault();
			}
		});
	}
	
	if(opts.polishUIDefs){
		await opts.polishUIDefs(appObj,uiDefs);
	}

	//************************************************************************
	//Create AppUI:
	//************************************************************************
	{
		let uiDef;
		let frg=new DocumentFragment();
		frg.$_pxy=appObj;
		VFACT.pushNameHost(appObj);
		for(uiDef of uiDefs){
			VFACT.createObj(uiDef,frg);
		}		
		VFACT.popNameHost(appObj);
		appObj.webObj.appendChild(frg);
		appObj.OnAppCreate();
	}
	return appObj;
};

VFACT.createApp=createApp;
VFACT.initApp=initApp;

var diskInfo = [
	{
		"name": "coke",
		"versionIdx": 217,
		"zip": "coke.zip"
	},
	{
		"name": "-tabos",
		"versionIdx": 92,
		"zip": "tabos.zip"
	},
	{
		"name": "-homekit",
		"versionIdx": 167,
		"zip": "homekit.zip"
	},
	{
		"name": "-terminal",
		"versionIdx": 65,
		"zip": "terminal.zip"
	},
	{
		"name": "-files",
		"versionIdx": 67,
		"zip": "files.zip"
	},
	{
		"name": "-tabedit",
		"versionIdx": 101,
		"zip": "tabedit.zip"
	},
	{
		"name": "-editkit",
		"versionIdx": 152,
		"zip": "editkit.zip"
	},
	{
		"name": "-books",
		"versionIdx": 21,
		"zip": "books.zip"
	},
	{
		"name": "-aichat",
		"versionIdx": 74,
		"zip": "aichat.zip"
	},
	{
		"name": "-StdUI",
		"versionIdx": 317,
		"zip": "StdUI.zip"
	},
	{
		"name": "-MobileHome",
		"versionIdx": 7,
		"zip": "MobileHome.zip"
	}
];

var mobileDiskInfo = [
	{
		"name": "coke",
		"versionIdx": 217,
		"zip": "coke.zip"
	},
	{
		"name": "-tabos",
		"versionIdx": 92,
		"zip": "tabos.zip"
	},
	{
		"name": "-homekit",
		"versionIdx": 167,
		"zip": "homekit.zip"
	},
	{
		"name": "-terminal",
		"versionIdx": 65,
		"zip": "terminal.zip"
	},
	{
		"name": "-files",
		"versionIdx": 67,
		"zip": "files.zip"
	},
	{
		"name": "-books",
		"versionIdx": 21,
		"zip": "books.zip"
	},
	{
		"name": "-aichat",
		"versionIdx": 74,
		"zip": "aichat.zip"
	},
	{
		"name": "-StdUI",
		"versionIdx": 317,
		"zip": "StdUI.zip"
	},
	{
		"name": "-MobileHome",
		"versionIdx": 7,
		"zip": "MobileHome.zip"
	}
];

var previewDiskInfo = [
	{
		"name": "coke",
		"versionIdx": 217,
		"zip": "coke.zip"
	},
	{
		"name": "-tabos",
		"versionIdx": 92,
		"zip": "tabos.zip"
	},
	{
		"name": "-homekit",
		"versionIdx": 167,
		"zip": "homekit.zip"
	},
	{
		"name": "-aichat",
		"versionIdx": 74,
		"zip": "aichat.zip"
	},
	{
		"name": "-StdUI",
		"versionIdx": 317,
		"zip": "StdUI.zip"
	},
	{
		"name": "-PVHome",
		"versionIdx": 15,
		"zip": "PVHome.zip"
	}
];

//Auto genterated by Cody
/*}#Imports*/
var cfgURL=import.meta.url+"1GFLQHQ1R0;";
/*#{StartDoc*/
/*}#StartDoc*/
let darkMode=false;
darkMode=VFACT.darkMode===null?darkMode:VFACT.darkMode;
VFACT.darkMode=darkMode;
if(!window.codyAppCfgs){
	window.codyAppCfgs={};
}
/*#{StartObj*/
/*}#StartObj*/
//----------------------------------------------------------------------------
let appCfg=window.codyAppCfgs[cfgURL]||{//"jaxId":"1GFLQHQ1Q0"
	"darkMode":darkMode,"version":"0.0.1",
	"txtSize":{
		"small":12,"mid":16,"big":20
	},
	"size":{
	},
	"color":{
	},
	"workerVsnIdx":0,
	/*#{ExAttrs*/
	/*}#ExAttrs*/
};
window.codyAppCfgs[cfgURL]=appCfg;
appCfg.lanCode=VFACT.lanCode===null?"EN":(VFACT.lanCode||"EN");
VFACT.lanCode=appCfg.lanCode;
if(!VFACT.appCfg){
	VFACT.appCfg=appCfg;
	window.jaxAppCfg=appCfg;
}
appCfg.applyCfg=function(){
	let majorCfg,attrName,cAttr,mAttr;
	majorCfg=VFACT.appCfg||window.jaxAppCfg;
	if(majorCfg && majorCfg!==appCfg){
		for(attrName in appCfg){
			if(attrName in majorCfg){
				cAttr=appCfg[attrName];
				mAttr=majorCfg[attrName];
				if(typeof(cAttr)==="object"){
					if(typeof(mAttr)==="object"){
						Object.assign(cAttr,mAttr);
					}
				}else if(attrName!=="applyCfg" && attrName!=="proxyCfg"){
					appCfg[attrName]=mAttr;
				}
			}
		}
	}
};
appCfg.proxyCfg=function(proxy){
	if(window.codyAppCfgs[cfgURL]===appCfg){
		window.codyAppCfgs[cfgURL]=proxy;
	}
	appCfg=proxy;
};

/*#{EndDoc*/
{
	let host=location.host;
	let pts=host.split(".");
	let appId;
	if(pts[1]==="apps"){
		appId=pts[0];
		appCfg.isSetupApps=true;
		appCfg.appId=appId;
		appCfg.diskInfo=mobileDiskInfo;
		appCfg.minCokeVsn=177;
	}else if(host.startsWith("pv.")){
		appCfg.isPreview=true;
		appCfg.diskInfo=previewDiskInfo;
		appCfg.minCokeVsn=177;
	}else if(VFACT.appParams.key&&VFACT.appParams.slot&&VFACT.appParams.userId){
		appCfg.isPreview=true;
		appCfg.diskInfo=previewDiskInfo;
		appCfg.minCokeVsn=177;
	}else if(window.screen.width<500){
		appCfg.isMobile=true;
		appCfg.diskInfo=mobileDiskInfo;
		appCfg.minCokeVsn=177;
		appId=VFACT.appParams.app;
		if(appId){
			appCfg.appId=appId;
		}
	}else {
		appCfg.isMobile=false;
		appCfg.diskInfo=diskInfo;
		appCfg.minCokeVsn=177;
		appId=VFACT.appParams.app;
		if(appId){
			appCfg.appId=appId;
		}
	}
}
/*Cody Project Doc*/
//{
//	"jaxId": "1GFLQHQ1R0",
//	"attrs": {
//		"localVars": {
//			"jaxId": "1GFLQHQ1R1",
//			"attrs": {
//				"darkMode": "false"
//			}
//		},
//		"editObjs": {
//			"jaxId": "1GFLQHQ1R2",
//			"attrs": {
//				"appCfg": {
//					"jaxId": "1GFLQHQ1Q0",
//					"attrs": {
//						"darkMode": "#darkMode",
//						"version": "0.0.1",
//						"txtSize": {
//							"jaxId": "1GFLQHQ1R3",
//							"attrs": {
//								"small": "12",
//								"mid": "16",
//								"big": "20"
//							}
//						},
//						"size": {
//							"jaxId": "1GFLQHQ1R4",
//							"attrs": {}
//						},
//						"color": {
//							"jaxId": "1GFLQHQ1R5",
//							"attrs": {}
//						},
//						"workerVsnIdx": {
//							"type": "int",
//							"valText": "0"
//						}
//					}
//				}
//			}
//		}
//	}
//}

/*!

JSZip v3.6.0 - A JavaScript class for generating and reading zip files
<http://stuartk.com/jszip>

(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.

JSZip uses the library pako released under the MIT license :
https://github.com/nodeca/pako/blob/master/LICENSE
*/
let setTimeout$1;
setTimeout$1 = function(callback, time) {
    let pms=new Promise((resolved,reject)=>{
        resolved(true);
    });
    pms.then(()=>{
        callback();
    });
    //orgWindow.setTimeout(()=>{callback();}, time);
};
let JSZip;
//var setTimeout=window.setTimeout;
{
	let window={};
	!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else {("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e();}}(function(){return function s(a,o,u){function h(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(f)return f(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return h(t||e)},i,i.exports,s,a,o,u);}return o[r].exports}for(var f="function"==typeof require&&require,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(l,t,n){(function(r){!function(e){"object"==typeof n&&void 0!==t?t.exports=e():("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).JSZip=e();}(function(){return function s(a,o,u){function h(t,e){if(!o[t]){if(!a[t]){var r="function"==typeof l&&l;if(!e&&r)return r(t,!0);if(f)return f(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[t]={exports:{}};a[t][0].call(i.exports,function(e){return h(a[t][1][e]||e)},i,i.exports,s,a,o,u);}return o[t].exports}for(var f="function"==typeof l&&l,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(l,t,n){(function(r){!function(e){"object"==typeof n&&void 0!==t?t.exports=e():("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).JSZip=e();}(function(){return function s(a,o,u){function h(t,e){if(!o[t]){if(!a[t]){var r="function"==typeof l&&l;if(!e&&r)return r(t,!0);if(f)return f(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[t]={exports:{}};a[t][0].call(i.exports,function(e){return h(a[t][1][e]||e)},i,i.exports,s,a,o,u);}return o[t].exports}for(var f="function"==typeof l&&l,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(l,t,n){(function(r){!function(e){"object"==typeof n&&void 0!==t?t.exports=e():("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).JSZip=e();}(function(){return function s(a,o,u){function h(t,e){if(!o[t]){if(!a[t]){var r="function"==typeof l&&l;if(!e&&r)return r(t,!0);if(f)return f(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[t]={exports:{}};a[t][0].call(i.exports,function(e){return h(a[t][1][e]||e)},i,i.exports,s,a,o,u);}return o[t].exports}for(var f="function"==typeof l&&l,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(l,t,n){(function(r){!function(e){"object"==typeof n&&void 0!==t?t.exports=e():("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).JSZip=e();}(function(){return function s(a,o,u){function h(t,e){if(!o[t]){if(!a[t]){var r="function"==typeof l&&l;if(!e&&r)return r(t,!0);if(f)return f(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[t]={exports:{}};a[t][0].call(i.exports,function(e){return h(a[t][1][e]||e)},i,i.exports,s,a,o,u);}return o[t].exports}for(var f="function"==typeof l&&l,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(l,t,n){(function(r){!function(e){"object"==typeof n&&void 0!==t?t.exports=e():("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).JSZip=e();}(function(){return function s(a,o,u){function h(t,e){if(!o[t]){if(!a[t]){var r="function"==typeof l&&l;if(!e&&r)return r(t,!0);if(f)return f(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[t]={exports:{}};a[t][0].call(i.exports,function(e){return h(a[t][1][e]||e)},i,i.exports,s,a,o,u);}return o[t].exports}for(var f="function"==typeof l&&l,e=0;e<u.length;e++)h(u[e]);return h}({1:[function(e,t,r){var c=e("./utils"),l=e("./support"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.encode=function(e){for(var t,r,n,i,s,a,o,u=[],h=0,f=e.length,l=f,d="string"!==c.getTypeOf(e);h<e.length;)l=f-h,n=d?(t=e[h++],r=h<f?e[h++]:0,h<f?e[h++]:0):(t=e.charCodeAt(h++),r=h<f?e.charCodeAt(h++):0,h<f?e.charCodeAt(h++):0),i=t>>2,s=(3&t)<<4|r>>4,a=1<l?(15&r)<<2|n>>6:64,o=2<l?63&n:64,u.push(p.charAt(i)+p.charAt(s)+p.charAt(a)+p.charAt(o));return u.join("")},r.decode=function(e){var t,r,n,i,s,a,o=0,u=0;if("data:"===e.substr(0,"data:".length))throw new Error("Invalid base64 input, it looks like a data url.");var h,f=3*(e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"")).length/4;if(e.charAt(e.length-1)===p.charAt(64)&&f--,e.charAt(e.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(h=l.uint8array?new Uint8Array(0|f):new Array(0|f);o<e.length;)t=p.indexOf(e.charAt(o++))<<2|(i=p.indexOf(e.charAt(o++)))>>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),h[u++]=t,64!==s&&(h[u++]=r),64!==a&&(h[u++]=n);return h};},{"./support":30,"./utils":32}],2:[function(e,t,r){var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i;}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o;},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(e){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate");},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){var n=e("./utils"),a=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s<i;s++)e=e>>>8^n[255&(e^t[s])];return -1^e}(0|t,e,e.length):function(e,t,r){var n=a,i=0+r;e^=-1;for(var s=0;s<i;s++)e=e>>>8^n[255&(e^t.charCodeAt(s))];return -1^e}(0|t,e,e.length):0};},{"./utils":32}],5:[function(e,t,r){r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null;},{}],6:[function(e,t,r){var n;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n};},{lie:37}],7:[function(e,t,r){var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function u(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={};}r.magic="\b\0",s.inherits(u,a),u.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1);},u.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0);},u.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null;},u.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta});};},r.compressWorker=function(e){return new u("Deflate",e)},r.uncompressWorker=function(){return new u("Inflate",{})};},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){function I(e,t){var r,n="";for(r=0;r<t;r++)n+=String.fromCharCode(255&e),e>>>=8;return n}function i(e,t,r,n,i,s){var a,o,u=e.file,h=e.compression,f=s!==B.utf8encode,l=O.transformTo("string",s(u.name)),d=O.transformTo("string",B.utf8encode(u.name)),c=u.comment,p=O.transformTo("string",s(c)),m=O.transformTo("string",B.utf8encode(c)),_=d.length!==u.name.length,g=m.length!==c.length,v="",b="",w="",y=u.dir,k=u.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),f||!_&&!g||(S|=2048);var z,E=0,C=0;y&&(E|=16),"UNIX"===i?(C=798,E|=((z=u.unixPermissions)||(z=y?16893:33204),(65535&z)<<16)):(C=20,E|=63&(u.dosPermissions||0)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v+="up"+I((b=I(1,1)+I(T(l),4)+d).length,2)+b),g&&(v+="uc"+I((w=I(1,1)+I(T(p),4)+m).length,2)+w);var A="";return A+="\n\0",A+=I(S,2),A+=h.magic,A+=I(a,2),A+=I(o,2),A+=I(x.crc32,4),A+=I(x.compressedSize,4),A+=I(x.uncompressedSize,4),A+=I(l.length,2),A+=I(v.length,2),{fileRecord:R.LOCAL_FILE_HEADER+A+l+v,dirRecord:R.CENTRAL_FILE_HEADER+I(C,2)+A+I(p.length,2)+"\0\0\0\0"+I(E,4)+I(n,4)+l+v+p}}var O=e("../utils"),s=e("../stream/GenericWorker"),B=e("../utf8"),T=e("../crc32"),R=e("../signature");function n(e,t,r,n){s.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[];}O.inherits(n,s),n.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,s.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}));},n.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=i(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}});}else this.accumulate=!0;},n.prototype.closedSource=function(e){this.accumulate=!1;var t,r=this.streamFiles&&!e.file.dir,n=i(e,r,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(n.dirRecord),r)this.push({data:(t=e,R.DATA_DESCRIPTOR+I(t.crc32,4)+I(t.compressedSize,4)+I(t.uncompressedSize,4)),meta:{percent:100}});else for(this.push({data:n.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null;},n.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t<this.dirRecords.length;t++)this.push({data:this.dirRecords[t],meta:{percent:100}});var r,n,i,s,a,o,u=this.bytesWritten-e,h=(r=this.dirRecords.length,n=u,i=e,s=this.zipComment,a=this.encodeFileName,o=O.transformTo("string",a(s)),R.CENTRAL_DIRECTORY_END+"\0\0\0\0"+I(r,2)+I(r,2)+I(n,4)+I(i,4)+I(o.length,2)+o);this.push({data:h,meta:{percent:100}});},n.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume();},n.prototype.registerPrevious=function(e){this._sources.push(e);var t=this;return e.on("data",function(e){t.processChunk(e);}),e.on("end",function(){t.closedSource(t.previous.streamInfo),t._sources.length?t.prepareNextSource():t.end();}),e.on("error",function(e){t.error(e);}),this},n.prototype.resume=function(){return !!s.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},n.prototype.error=function(e){var t=this._sources;if(!s.prototype.error.call(this,e))return !1;for(var r=0;r<t.length;r++)try{t[r].error(e);}catch(e){}return !0},n.prototype.lock=function(){s.prototype.lock.call(this);for(var e=this._sources,t=0;t<e.length;t++)e[t].lock();},t.exports=n;},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(e,t,r){var h=e("../compressions"),n=e("./ZipFileWorker");r.generateWorker=function(e,a,t){var o=new n(a.streamFiles,t,a.platform,a.encodeFileName),u=0;try{e.forEach(function(e,t){u++;var r=function(e,t){var r=e||t,n=h[r];if(!n)throw new Error(r+" is not a valid compression method !");return n}(t.options.compression,a.compression),n=t.options.compressionOptions||a.compressionOptions||{},i=t.dir,s=t.date;t._compressWorker(r,n).withStreamInfo("file",{name:e,dir:i,date:s,comment:t.comment||"",unixPermissions:t.unixPermissions,dosPermissions:t.dosPermissions}).pipe(o);}),o.entriesCount=u;}catch(e){o.error(e);}return o};},{"../compressions":3,"./ZipFileWorker":8}],10:[function(e,t,r){function n(){if(!(this instanceof n))return new n;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files={},this.comment=null,this.root="",this.clone=function(){var e=new n;for(var t in this)"function"!=typeof this[t]&&(e[t]=this[t]);return e};}(n.prototype=e("./object")).loadAsync=e("./load"),n.support=e("./support"),n.defaults=e("./defaults"),n.version="3.5.0",n.loadAsync=function(e,t){return (new n).loadAsync(e,t)},n.external=e("./external"),t.exports=n;},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(e,t,r){var n=e("./utils"),i=e("./external"),o=e("./utf8"),u=e("./zipEntries"),s=e("./stream/Crc32Probe"),h=e("./nodejsUtils");function f(n){return new i.Promise(function(e,t){var r=n.decompressed.getContentWorker().pipe(new s);r.on("error",function(e){t(e);}).on("end",function(){r.streamInfo.crc32!==n.decompressed.crc32?t(new Error("Corrupted zip : CRC32 mismatch")):e();}).resume();})}t.exports=function(e,s){var a=this;return s=n.extend(s||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:o.utf8decode}),h.isNode&&h.isStream(e)?i.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):n.prepareContent("the loaded zip file",e,!0,s.optimizedBinaryString,s.base64).then(function(e){var t=new u(s);return t.load(e),t}).then(function(e){var t=[i.Promise.resolve(e)],r=e.files;if(s.checkCRC32)for(var n=0;n<r.length;n++)t.push(f(r[n]));return i.Promise.all(t)}).then(function(e){for(var t=e.shift(),r=t.files,n=0;n<r.length;n++){var i=r[n];a.file(i.fileNameStr,i.decompressed,{binary:!0,optimizedBinaryString:!0,date:i.date,dir:i.dir,comment:i.fileCommentStr.length?i.fileCommentStr:null,unixPermissions:i.unixPermissions,dosPermissions:i.dosPermissions,createFolders:s.createFolders});}return t.zipComment.length&&(a.comment=t.zipComment),a})};},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(e,t,r){var n=e("../utils"),i=e("../stream/GenericWorker");function s(e,t){i.call(this,"Nodejs stream input adapter for "+e),this._upstreamEnded=!1,this._bindStream(t);}n.inherits(s,i),s.prototype._bindStream=function(e){var t=this;(this._stream=e).pause(),e.on("data",function(e){t.push({data:e,meta:{percent:0}});}).on("error",function(e){t.isPaused?this.generatedError=e:t.error(e);}).on("end",function(){t.isPaused?t._upstreamEnded=!0:t.end();});},s.prototype.pause=function(){return !!i.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},t.exports=s;},{"../stream/GenericWorker":28,"../utils":32}],13:[function(e,t,r){var i=e("readable-stream").Readable;function n(e,t,r){i.call(this,t),this._helper=e;var n=this;e.on("data",function(e,t){n.push(e)||n._helper.pause(),r&&r(t);}).on("error",function(e){n.emit("error",e);}).on("end",function(){n.push(null);});}e("../utils").inherits(n,i),n.prototype._read=function(){this._helper.resume();},t.exports=n;},{"../utils":32,"readable-stream":16}],14:[function(e,t,r){t.exports={isNode:"undefined"!=typeof Buffer,newBufferFrom:function(e,t){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,t);if("number"==typeof e)throw new Error('The "data" argument must not be a number');return new Buffer(e,t)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var t=new Buffer(e);return t.fill(0),t},isBuffer:function(e){return Buffer.isBuffer(e)},isStream:function(e){return e&&"function"==typeof e.on&&"function"==typeof e.pause&&"function"==typeof e.resume}};},{}],15:[function(e,t,r){function s(e,t,r){var n,i=f.getTypeOf(t),s=f.extend(r||{},d);s.date=s.date||new Date,null!==s.compression&&(s.compression=s.compression.toUpperCase()),"string"==typeof s.unixPermissions&&(s.unixPermissions=parseInt(s.unixPermissions,8)),s.unixPermissions&&16384&s.unixPermissions&&(s.dir=!0),s.dosPermissions&&16&s.dosPermissions&&(s.dir=!0),s.dir&&(e=h(e)),s.createFolders&&(n=function(e){"/"===e.slice(-1)&&(e=e.substring(0,e.length-1));var t=e.lastIndexOf("/");return 0<t?e.substring(0,t):""}(e))&&g.call(this,n,!0);var a,o="string"===i&&!1===s.binary&&!1===s.base64;r&&void 0!==r.binary||(s.binary=!o),(t instanceof c&&0===t.uncompressedSize||s.dir||!t||0===t.length)&&(s.base64=!1,s.binary=!0,t="",s.compression="STORE",i="string"),a=t instanceof c||t instanceof l?t:m.isNode&&m.isStream(t)?new _(e,t):f.prepareContent(e,t,s.binary,s.optimizedBinaryString,s.base64);var u=new p(e,a,s);this.files[e]=u;}function h(e){return "/"!==e.slice(-1)&&(e+="/"),e}var i=e("./utf8"),f=e("./utils"),l=e("./stream/GenericWorker"),a=e("./stream/StreamHelper"),d=e("./defaults"),c=e("./compressedObject"),p=e("./zipObject"),o=e("./generate"),m=e("./nodejsUtils"),_=e("./nodejs/NodejsStreamInputAdapter"),g=function(e,t){return t=void 0!==t?t:d.createFolders,e=h(e),this.files[e]||s.call(this,e,null,{dir:!0,createFolders:t}),this.files[e]};function u(e){return "[object RegExp]"===Object.prototype.toString.call(e)}var n={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(e){var t,r,n;for(t in this.files)this.files.hasOwnProperty(t)&&(n=this.files[t],(r=t.slice(this.root.length,t.length))&&t.slice(0,this.root.length)===this.root&&e(r,n));},filter:function(r){var n=[];return this.forEach(function(e,t){r(e,t)&&n.push(t);}),n},file:function(e,t,r){if(1!==arguments.length)return e=this.root+e,s.call(this,e,t,r),this;if(u(e)){var n=e;return this.filter(function(e,t){return !t.dir&&n.test(e)})}var i=this.files[this.root+e];return i&&!i.dir?i:null},folder:function(r){if(!r)return this;if(u(r))return this.filter(function(e,t){return t.dir&&r.test(e)});var e=this.root+r,t=g.call(this,e),n=this.clone();return n.root=t.name,n},remove:function(r){r=this.root+r;var e=this.files[r];if(e||("/"!==r.slice(-1)&&(r+="/"),e=this.files[r]),e&&!e.dir)delete this.files[r];else for(var t=this.filter(function(e,t){return t.name.slice(0,r.length)===r}),n=0;n<t.length;n++)delete this.files[t[n].name];return this},generate:function(e){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(e){var t,r={};try{if((r=f.extend(e||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:i.utf8encode})).type=r.type.toLowerCase(),r.compression=r.compression.toUpperCase(),"binarystring"===r.type&&(r.type="string"),!r.type)throw new Error("No output type specified.");f.checkSupport(r.type),"darwin"!==r.platform&&"freebsd"!==r.platform&&"linux"!==r.platform&&"sunos"!==r.platform||(r.platform="UNIX"),"win32"===r.platform&&(r.platform="DOS");var n=r.comment||this.comment||"";t=o.generateWorker(this,r,n);}catch(e){(t=new l("error")).error(e);}return new a(t,r.type||"string",r.mimeType)},generateAsync:function(e,t){return this.generateInternalStream(e).accumulate(t)},generateNodeStream:function(e,t){return (e=e||{}).type||(e.type="nodebuffer"),this.generateInternalStream(e).toNodejsStream(t)}};t.exports=n;},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(e,t,r){t.exports=e("stream");},{stream:void 0}],17:[function(e,t,r){var n=e("./DataReader");function i(e){n.call(this,e);for(var t=0;t<this.data.length;t++)e[t]=255&e[t];}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data[this.zero+e]},i.prototype.lastIndexOfSignature=function(e){for(var t=e.charCodeAt(0),r=e.charCodeAt(1),n=e.charCodeAt(2),i=e.charCodeAt(3),s=this.length-4;0<=s;--s)if(this.data[s]===t&&this.data[s+1]===r&&this.data[s+2]===n&&this.data[s+3]===i)return s-this.zero;return -1},i.prototype.readAndCheckSignature=function(e){var t=e.charCodeAt(0),r=e.charCodeAt(1),n=e.charCodeAt(2),i=e.charCodeAt(3),s=this.readData(4);return t===s[0]&&r===s[1]&&n===s[2]&&i===s[3]},i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return [];var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./DataReader":18}],18:[function(e,t,r){var n=e("../utils");function i(e){this.data=e,this.length=e.length,this.index=0,this.zero=0;}i.prototype={checkOffset:function(e){this.checkIndex(this.index+e);},checkIndex:function(e){if(this.length<this.zero+e||e<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+e+"). Corrupted zip ?")},setIndex:function(e){this.checkIndex(e),this.index=e;},skip:function(e){this.setIndex(this.index+e);},byteAt:function(e){},readInt:function(e){var t,r=0;for(this.checkOffset(e),t=this.index+e-1;t>=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(e){},lastIndexOfSignature:function(e){},readAndCheckSignature:function(e){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i;},{"../utils":32}],19:[function(e,t,r){var n=e("./Uint8ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){var n=e("./DataReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){var n=e("./ArrayReader");function i(e){n.call(this,e);}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i;},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),u=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new u(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)};},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b";},{}],24:[function(e,t,r){var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e;}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta});},t.exports=s;},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0);}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e);},t.exports=s;},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0);}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length;}i.prototype.processChunk.call(this,e);},t.exports=s;},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat();},function(e){t.error(e);});}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null;},s.prototype.resume=function(){return !!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0));},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return !1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t);}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s;},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null;}n.prototype={push:function(e){this.emit("data",e);},end:function(){if(this.isFinished)return !1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0;}catch(e){this.emit("error",e);}return !0},error:function(e){return !this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[];},emit:function(e,t){if(this._listeners[e])for(var r=0;r<this._listeners[e].length;r++)this._listeners[e][r].call(this,t);},pipe:function(e){return e.registerPrevious(this)},registerPrevious:function(e){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=e.streamInfo,this.mergeStreamInfo(),this.previous=e;var t=this;return e.on("data",function(e){t.processChunk(e);}),e.on("end",function(){t.end();}),e.on("error",function(e){t.error(e);}),this},pause:function(){return !this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return !1;var e=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),e=!0),this.previous&&this.previous.resume(),!e},flush:function(){},processChunk:function(e){this.push(e);},withStreamInfo:function(e,t){return this.extraStreamInfo[e]=t,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var e in this.extraStreamInfo)this.extraStreamInfo.hasOwnProperty(e)&&(this.streamInfo[e]=this.extraStreamInfo[e]);},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock();},toString:function(){var e="Worker "+this.name;return this.previous?this.previous+" -> "+e:e}},t.exports=n;},{}],29:[function(e,t,r){var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),f=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter");}catch(e){}function u(e,t,r){var n=t;switch(t){case"blob":case"arraybuffer":n="uint8array";break;case"base64":n="string";}try{this._internalType=n,this._outputType=t,this._mimeType=r,h.checkSupport(n),this._worker=e.pipe(new i(n)),e.lock();}catch(e){this._worker=new s("error"),this._worker.error(e);}}u.prototype={accumulate:function(e){return o=this,u=e,new a.Promise(function(t,r){var n=[],i=o._internalType,s=o._outputType,a=o._mimeType;o.on("data",function(e,t){n.push(e),u&&u(t);}).on("error",function(e){n=[],r(e);}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return f.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r<t.length;r++)s+=t[r].length;switch(e){case"string":return t.join("");case"array":return Array.prototype.concat.apply([],t);case"uint8array":for(i=new Uint8Array(s),r=0;r<t.length;r++)i.set(t[r],n),n+=t[r].length;return i;case"nodebuffer":return Buffer.concat(t);default:throw new Error("concat : unsupported type '"+e+"'")}}(i,n),a);t(e);}catch(e){r(e);}n=[];}).resume();});var o,u;},on:function(e,t){var r=this;return "data"===e?this._worker.on(e,function(e){t.call(r,e.data,e.meta);}):this._worker.on(e,function(){h.delay(t,arguments,r);}),this},resume:function(){return h.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(e){if(h.checkSupport("nodestream"),"nodebuffer"!==this._outputType)throw new Error(this._outputType+" is not supported by this method");return new o(this,{objectMode:"nodebuffer"!==this._outputType},e)}},t.exports=u;},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(e,t,r){if(r.base64=!0,r.array=!0,r.string=!0,r.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,r.nodebuffer="undefined"!=typeof Buffer,r.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)r.blob=!1;else {var n=new ArrayBuffer(0);try{r.blob=0===new Blob([n],{type:"application/zip"}).size;}catch(e){try{var i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);i.append(n),r.blob=0===i.getBlob("application/zip").size;}catch(e){r.blob=!1;}}}try{r.nodestream=!!e("readable-stream").Readable;}catch(e){r.nodestream=!1;}},{"readable-stream":16}],31:[function(e,t,s){for(var o=e("./utils"),u=e("./support"),r=e("./nodejsUtils"),n=e("./stream/GenericWorker"),h=new Array(256),i=0;i<256;i++)h[i]=252<=i?6:248<=i?5:240<=i?4:224<=i?3:192<=i?2:1;function a(){n.call(this,"utf-8 decode"),this.leftOver=null;}function f(){n.call(this,"utf-8 encode");}h[254]=h[254]=1,s.utf8encode=function(e){return u.nodebuffer?r.newBufferFrom(e,"utf-8"):function(e){var t,r,n,i,s,a=e.length,o=0;for(i=0;i<a;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),o+=r<128?1:r<2048?2:r<65536?3:4;for(t=u.uint8array?new Uint8Array(o):new Array(o),i=s=0;s<o;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),r<128?t[s++]=r:(r<2048?t[s++]=192|r>>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return u.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t<s;)if((n=e[t++])<128)a[r++]=n;else if(4<(i=h[n]))a[r++]=65533,t+=i-1;else {for(n&=2===i?31:3===i?15:7;1<i&&t<s;)n=n<<6|63&e[t++],i--;1<i?a[r++]=65533:n<65536?a[r++]=n:(n-=65536,a[r++]=55296|n>>10&1023,a[r++]=56320|1023&n);}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(u.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(u.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(u.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length);}else t=this.leftOver.concat(t);this.leftOver=null;}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+h[e[r]]>t?r:t}(t),i=t;n!==t.length&&(u.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta});},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null);},s.Utf8DecodeWorker=a,o.inherits(f,n),f.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta});},s.Utf8EncodeWorker=f;},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,o){var u=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),n=e("set-immediate-shim"),f=e("./external");function i(e){return e}function l(e,t){for(var r=0;r<e.length;++r)t[r]=255&e.charCodeAt(r);return t}o.newBlob=function(t,r){o.checkSupport("blob");try{return new Blob([t],{type:r})}catch(e){try{var n=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return n.append(t),n.getBlob(r)}catch(e){throw new Error("Bug : can't construct the Blob.")}}};var s={stringifyByChunk:function(e,t,r){var n=[],i=0,s=e.length;if(s<=r)return String.fromCharCode.apply(null,e);for(;i<s;)"array"===t||"nodebuffer"===t?n.push(String.fromCharCode.apply(null,e.slice(i,Math.min(i+r,s)))):n.push(String.fromCharCode.apply(null,e.subarray(i,Math.min(i+r,s)))),i+=r;return n.join("")},stringifyByChar:function(e){for(var t="",r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return t},applyCanBeUsed:{uint8array:function(){try{return u.uint8array&&1===String.fromCharCode.apply(null,new Uint8Array(1)).length}catch(e){return !1}}(),nodebuffer:function(){try{return u.nodebuffer&&1===String.fromCharCode.apply(null,r.allocBuffer(1)).length}catch(e){return !1}}()}};function a(e){var t=65536,r=o.getTypeOf(e),n=!0;if("uint8array"===r?n=s.applyCanBeUsed.uint8array:"nodebuffer"===r&&(n=s.applyCanBeUsed.nodebuffer),n)for(;1<t;)try{return s.stringifyByChunk(e,r,t)}catch(e){t=Math.floor(t/2);}return s.stringifyByChar(e)}function d(e,t){for(var r=0;r<e.length;r++)t[r]=e[r];return t}o.applyFromCharCode=a;var c={};c.string={string:i,array:function(e){return l(e,new Array(e.length))},arraybuffer:function(e){return c.string.uint8array(e).buffer},uint8array:function(e){return l(e,new Uint8Array(e.length))},nodebuffer:function(e){return l(e,r.allocBuffer(e.length))}},c.array={string:a,array:i,arraybuffer:function(e){return new Uint8Array(e).buffer},uint8array:function(e){return new Uint8Array(e)},nodebuffer:function(e){return r.newBufferFrom(e)}},c.arraybuffer={string:function(e){return a(new Uint8Array(e))},array:function(e){return d(new Uint8Array(e),new Array(e.byteLength))},arraybuffer:i,uint8array:function(e){return new Uint8Array(e)},nodebuffer:function(e){return r.newBufferFrom(new Uint8Array(e))}},c.uint8array={string:a,array:function(e){return d(e,new Array(e.length))},arraybuffer:function(e){return e.buffer},uint8array:i,nodebuffer:function(e){return r.newBufferFrom(e)}},c.nodebuffer={string:a,array:function(e){return d(e,new Array(e.length))},arraybuffer:function(e){return c.nodebuffer.uint8array(e).buffer},uint8array:function(e){return d(e,new Uint8Array(e.length))},nodebuffer:i},o.transformTo=function(e,t){if(t=t||"",!e)return t;o.checkSupport(e);var r=o.getTypeOf(t);return c[r][e](t)},o.getTypeOf=function(e){return "string"==typeof e?"string":"[object Array]"===Object.prototype.toString.call(e)?"array":u.nodebuffer&&r.isBuffer(e)?"nodebuffer":u.uint8array&&e instanceof Uint8Array?"uint8array":u.arraybuffer&&e instanceof ArrayBuffer?"arraybuffer":void 0},o.checkSupport=function(e){if(!u[e.toLowerCase()])throw new Error(e+" is not supported by this platform")},o.MAX_VALUE_16BITS=65535,o.MAX_VALUE_32BITS=-1,o.pretty=function(e){var t,r,n="";for(r=0;r<(e||"").length;r++)n+="\\x"+((t=e.charCodeAt(r))<16?"0":"")+t.toString(16).toUpperCase();return n},o.delay=function(e,t,r){n(function(){e.apply(r||null,t||[]);});},o.inherits=function(e,t){function r(){}r.prototype=t.prototype,e.prototype=new r;},o.extend=function(){var e,t,r={};for(e=0;e<arguments.length;e++)for(t in arguments[e])arguments[e].hasOwnProperty(t)&&void 0===r[t]&&(r[t]=arguments[e][t]);return r},o.prepareContent=function(n,e,i,s,a){return f.Promise.resolve(e).then(function(n){return u.blob&&(n instanceof Blob||-1!==["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(n)))&&"undefined"!=typeof FileReader?new f.Promise(function(t,r){var e=new FileReader;e.onload=function(e){t(e.target.result);},e.onerror=function(e){r(e.target.error);},e.readAsArrayBuffer(n);}):n}).then(function(e){var t,r=o.getTypeOf(e);return r?("arraybuffer"===r?e=o.transformTo("uint8array",e):"string"===r&&(a?e=h.decode(e):i&&!0!==s&&(e=l(t=e,u.uint8array?new Uint8Array(t.length):new Array(t.length)))),e):f.Promise.reject(new Error("Can't read the data of '"+n+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})};},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"set-immediate-shim":54}],33:[function(e,t,r){var n=e("./reader/readerFor"),i=e("./utils"),s=e("./signature"),a=e("./zipEntry"),o=(e("./utf8"),e("./support"));function u(e){this.files=[],this.loadOptions=e;}u.prototype={checkSignature:function(e){if(!this.reader.readAndCheckSignature(e)){this.reader.index-=4;var t=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+i.pretty(t)+", expected "+i.pretty(e)+")")}},isSignature:function(e,t){var r=this.reader.index;this.reader.setIndex(e);var n=this.reader.readString(4)===t;return this.reader.setIndex(r),n},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var e=this.reader.readData(this.zipCommentLength),t=o.uint8array?"uint8array":"array",r=i.transformTo(t,e);this.zipComment=this.loadOptions.decodeFileName(r);},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var e,t,r,n=this.zip64EndOfCentralSize-44;0<n;)e=this.reader.readInt(2),t=this.reader.readInt(4),r=this.reader.readData(t),this.zip64ExtensibleData[e]={id:e,length:t,value:r};},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var e,t;for(e=0;e<this.files.length;e++)t=this.files[e],this.reader.setIndex(t.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),t.readLocalPart(this.reader),t.handleUTF8(),t.processAttributes();},readCentralDir:function(){var e;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER);)(e=new a({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(e);if(this.centralDirRecords!==this.files.length&&0!==this.centralDirRecords&&0===this.files.length)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var e=this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END);if(e<0)throw this.isSignature(0,s.LOCAL_FILE_HEADER)?new Error("Corrupted zip: can't find end of central directory"):new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");this.reader.setIndex(e);var t=e;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===i.MAX_VALUE_16BITS||this.diskWithCentralDirStart===i.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===i.MAX_VALUE_16BITS||this.centralDirRecords===i.MAX_VALUE_16BITS||this.centralDirSize===i.MAX_VALUE_32BITS||this.centralDirOffset===i.MAX_VALUE_32BITS){if(this.zip64=!0,(e=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(e),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral();}var r=this.centralDirOffset+this.centralDirSize;this.zip64&&(r+=20,r+=12+this.zip64EndOfCentralSize);var n=t-r;if(0<n)this.isSignature(t,s.CENTRAL_FILE_HEADER)||(this.reader.zero=n);else if(n<0)throw new Error("Corrupted zip: missing "+Math.abs(n)+" bytes.")},prepareReader:function(e){this.reader=n(e);},load:function(e){this.prepareReader(e),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles();}},t.exports=u;},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(e,t,r){var n=e("./reader/readerFor"),s=e("./utils"),i=e("./compressedObject"),a=e("./crc32"),o=e("./utf8"),u=e("./compressions"),h=e("./support");function f(e,t){this.options=e,this.loadOptions=t;}f.prototype={isEncrypted:function(){return 1==(1&this.bitFlag)},useUTF8:function(){return 2048==(2048&this.bitFlag)},readLocalPart:function(e){var t,r;if(e.skip(22),this.fileNameLength=e.readInt(2),r=e.readInt(2),this.fileName=e.readData(this.fileNameLength),e.skip(r),-1===this.compressedSize||-1===this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(null===(t=function(e){for(var t in u)if(u.hasOwnProperty(t)&&u[t].magic===e)return u[t];return null}(this.compressionMethod)))throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new i(this.compressedSize,this.uncompressedSize,this.crc32,t,e.readData(this.compressedSize));},readCentralPart:function(e){this.versionMadeBy=e.readInt(2),e.skip(2),this.bitFlag=e.readInt(2),this.compressionMethod=e.readString(2),this.date=e.readDate(),this.crc32=e.readInt(4),this.compressedSize=e.readInt(4),this.uncompressedSize=e.readInt(4);var t=e.readInt(2);if(this.extraFieldsLength=e.readInt(2),this.fileCommentLength=e.readInt(2),this.diskNumberStart=e.readInt(2),this.internalFileAttributes=e.readInt(2),this.externalFileAttributes=e.readInt(4),this.localHeaderOffset=e.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");e.skip(t),this.readExtraFields(e),this.parseZIP64ExtraField(e),this.fileComment=e.readData(this.fileCommentLength);},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var e=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0);},parseZIP64ExtraField:function(e){if(this.extraFields[1]){var t=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=t.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=t.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=t.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=t.readInt(4));}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4<i;)t=e.readInt(2),r=e.readInt(2),n=e.readData(r),this.extraFields[t]={id:t,length:r,value:n};e.setIndex(i);},handleUTF8:function(){var e=h.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else {var t=this.findExtraFieldUnicodePath();if(null!==t)this.fileNameStr=t;else {var r=s.transformTo(e,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(r);}var n=this.findExtraFieldUnicodeComment();if(null!==n)this.fileCommentStr=n;else {var i=s.transformTo(e,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(i);}}},findExtraFieldUnicodePath:function(){var e=this.extraFields[28789];if(e){var t=n(e.value);return 1!==t.readInt(1)?null:a(this.fileName)!==t.readInt(4)?null:o.utf8decode(t.readData(e.length-5))}return null},findExtraFieldUnicodeComment:function(){var e=this.extraFields[25461];if(e){var t=n(e.value);return 1!==t.readInt(1)?null:a(this.fileComment)!==t.readInt(4)?null:o.utf8decode(t.readData(e.length-5))}return null}},t.exports=f;},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(e,t,r){function n(e,t,r){this.name=e,this.dir=r.dir,this.date=r.date,this.comment=r.comment,this.unixPermissions=r.unixPermissions,this.dosPermissions=r.dosPermissions,this._data=t,this._dataBinary=r.binary,this.options={compression:r.compression,compressionOptions:r.compressionOptions};}var s=e("./stream/StreamHelper"),i=e("./stream/DataWorker"),a=e("./utf8"),o=e("./compressedObject"),u=e("./stream/GenericWorker");n.prototype={internalStream:function(e){var t=null,r="string";try{if(!e)throw new Error("No output type specified.");var n="string"===(r=e.toLowerCase())||"text"===r;"binarystring"!==r&&"text"!==r||(r="string"),t=this._decompressWorker();var i=!this._dataBinary;i&&!n&&(t=t.pipe(new a.Utf8EncodeWorker)),!i&&n&&(t=t.pipe(new a.Utf8DecodeWorker));}catch(e){(t=new u("error")).error(e);}return new s(t,r,"")},async:function(e,t){return this.internalStream(e).accumulate(t)},nodeStream:function(e,t){return this.internalStream(e||"nodebuffer").toNodejsStream(t)},_compressWorker:function(e,t){if(this._data instanceof o&&this._data.compression.magic===e.magic)return this._data.getCompressedWorker();var r=this._decompressWorker();return this._dataBinary||(r=r.pipe(new a.Utf8EncodeWorker)),o.createWorkerFrom(r,e,t)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof u?this._data:new i(this._data)}};for(var h=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],f=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},l=0;l<h.length;l++)n.prototype[h[l]]=f;t.exports=n;},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(e,f,t){(function(t){var r,n,e=t.MutationObserver||t.WebKitMutationObserver;if(e){var i=0,s=new e(h),a=t.document.createTextNode("");s.observe(a,{characterData:!0}),r=function(){a.data=i=++i%2;};}else if(t.setImmediate||void 0===t.MessageChannel)r="document"in t&&"onreadystatechange"in t.document.createElement("script")?function(){var e=t.document.createElement("script");e.onreadystatechange=function(){h(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null;},t.document.documentElement.appendChild(e);}:function(){setTimeout$1(h,0);};else {var o=new t.MessageChannel;o.port1.onmessage=h,r=function(){o.port2.postMessage(0);};}var u=[];function h(){var e,t;n=!0;for(var r=u.length;r;){for(t=u,u=[],e=-1;++e<r;)t[e]();r=u.length;}n=!1;}f.exports=function(e){1!==u.push(e)||n||r();};}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}],37:[function(e,t,r){var i=e("immediate");function h(){}var f={},s=["REJECTED"],a=["FULFILLED"],n=["PENDING"];function o(e){if("function"!=typeof e)throw new TypeError("resolver must be a function");this.state=n,this.queue=[],this.outcome=void 0,e!==h&&c(this,e);}function u(e,t,r){this.promise=e,"function"==typeof t&&(this.onFulfilled=t,this.callFulfilled=this.otherCallFulfilled),"function"==typeof r&&(this.onRejected=r,this.callRejected=this.otherCallRejected);}function l(t,r,n){i(function(){var e;try{e=r(n);}catch(e){return f.reject(t,e)}e===t?f.reject(t,new TypeError("Cannot resolve promise with itself")):f.resolve(t,e);});}function d(e){var t=e&&e.then;if(e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof t)return function(){t.apply(e,arguments);}}function c(t,e){var r=!1;function n(e){r||(r=!0,f.reject(t,e));}function i(e){r||(r=!0,f.resolve(t,e));}var s=p(function(){e(i,n);});"error"===s.status&&n(s.value);}function p(e,t){var r={};try{r.value=e(t),r.status="success";}catch(e){r.status="error",r.value=e;}return r}(t.exports=o).prototype.finally=function(t){if("function"!=typeof t)return this;var r=this.constructor;return this.then(function(e){return r.resolve(t()).then(function(){return e})},function(e){return r.resolve(t()).then(function(){throw e})})},o.prototype.catch=function(e){return this.then(null,e)},o.prototype.then=function(e,t){if("function"!=typeof e&&this.state===a||"function"!=typeof t&&this.state===s)return this;var r=new this.constructor(h);return this.state!==n?l(r,this.state===a?e:t,this.outcome):this.queue.push(new u(r,e,t)),r},u.prototype.callFulfilled=function(e){f.resolve(this.promise,e);},u.prototype.otherCallFulfilled=function(e){l(this.promise,this.onFulfilled,e);},u.prototype.callRejected=function(e){f.reject(this.promise,e);},u.prototype.otherCallRejected=function(e){l(this.promise,this.onRejected,e);},f.resolve=function(e,t){var r=p(d,t);if("error"===r.status)return f.reject(e,r.value);var n=r.value;if(n)c(e,n);else {e.state=a,e.outcome=t;for(var i=-1,s=e.queue.length;++i<s;)e.queue[i].callFulfilled(t);}return e},f.reject=function(e,t){e.state=s,e.outcome=t;for(var r=-1,n=e.queue.length;++r<n;)e.queue[r].callRejected(t);return e},o.resolve=function(e){return e instanceof this?e:f.resolve(new this(h),e)},o.reject=function(e){var t=new this(h);return f.reject(t,e)},o.all=function(e){var r=this;if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var n=e.length,i=!1;if(!n)return this.resolve([]);for(var s=new Array(n),a=0,t=-1,o=new this(h);++t<n;)u(e[t],t);return o;function u(e,t){r.resolve(e).then(function(e){s[t]=e,++a!==n||i||(i=!0,f.resolve(o,s));},function(e){i||(i=!0,f.reject(o,e));});}},o.race=function(e){if("[object Array]"!==Object.prototype.toString.call(e))return this.reject(new TypeError("must be an array"));var t=e.length,r=!1;if(!t)return this.resolve([]);for(var n,i=-1,s=new this(h);++i<t;)n=e[i],this.resolve(n).then(function(e){r||(r=!0,f.resolve(s,e));},function(e){r||(r=!0,f.reject(s,e));});return s};},{immediate:36}],38:[function(e,t,r){var n={};(0, e("./lib/utils/common").assign)(n,e("./lib/deflate"),e("./lib/inflate"),e("./lib/zlib/constants")),t.exports=n;},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(e,t,r){var a=e("./zlib/deflate"),o=e("./utils/common"),u=e("./utils/strings"),i=e("./zlib/messages"),s=e("./zlib/zstream"),h=Object.prototype.toString,f=0,l=-1,d=0,c=8;function p(e){if(!(this instanceof p))return new p(e);this.options=o.assign({level:l,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:d,to:""},e||{});var t=this.options;t.raw&&0<t.windowBits?t.windowBits=-t.windowBits:t.gzip&&0<t.windowBits&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(r!==f)throw new Error(i[r]);if(t.header&&a.deflateSetHeader(this.strm,t.header),t.dictionary){var n;if(n="string"==typeof t.dictionary?u.string2buf(t.dictionary):"[object ArrayBuffer]"===h.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,(r=a.deflateSetDictionary(this.strm,n))!==f)throw new Error(i[r]);this._dict_set=!0;}}function n(e,t){var r=new p(t);if(r.push(e,!0),r.err)throw r.msg||i[r.err];return r.result}p.prototype.push=function(e,t){var r,n,i=this.strm,s=this.options.chunkSize;if(this.ended)return !1;n=t===~~t?t:!0===t?4:0,"string"==typeof e?i.input=u.string2buf(e):"[object ArrayBuffer]"===h.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;do{if(0===i.avail_out&&(i.output=new o.Buf8(s),i.next_out=0,i.avail_out=s),1!==(r=a.deflate(i,n))&&r!==f)return this.onEnd(r),!(this.ended=!0);0!==i.avail_out&&(0!==i.avail_in||4!==n&&2!==n)||("string"===this.options.to?this.onData(u.buf2binstring(o.shrinkBuf(i.output,i.next_out))):this.onData(o.shrinkBuf(i.output,i.next_out)));}while((0<i.avail_in||0===i.avail_out)&&1!==r);return 4===n?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===f):2!==n||(this.onEnd(f),!(i.avail_out=0))},p.prototype.onData=function(e){this.chunks.push(e);},p.prototype.onEnd=function(e){e===f&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},r.Deflate=p,r.deflate=n,r.deflateRaw=function(e,t){return (t=t||{}).raw=!0,n(e,t)},r.gzip=function(e,t){return (t=t||{}).gzip=!0,n(e,t)};},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(e,t,r){var d=e("./zlib/inflate"),c=e("./utils/common"),p=e("./utils/strings"),m=e("./zlib/constants"),n=e("./zlib/messages"),i=e("./zlib/zstream"),s=e("./zlib/gzheader"),_=Object.prototype.toString;function a(e){if(!(this instanceof a))return new a(e);this.options=c.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&0<=t.windowBits&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(0<=t.windowBits&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),15<t.windowBits&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new i,this.strm.avail_out=0;var r=d.inflateInit2(this.strm,t.windowBits);if(r!==m.Z_OK)throw new Error(n[r]);this.header=new s,d.inflateGetHeader(this.strm,this.header);}function o(e,t){var r=new a(t);if(r.push(e,!0),r.err)throw r.msg||n[r.err];return r.result}a.prototype.push=function(e,t){var r,n,i,s,a,o,u=this.strm,h=this.options.chunkSize,f=this.options.dictionary,l=!1;if(this.ended)return !1;n=t===~~t?t:!0===t?m.Z_FINISH:m.Z_NO_FLUSH,"string"==typeof e?u.input=p.binstring2buf(e):"[object ArrayBuffer]"===_.call(e)?u.input=new Uint8Array(e):u.input=e,u.next_in=0,u.avail_in=u.input.length;do{if(0===u.avail_out&&(u.output=new c.Buf8(h),u.next_out=0,u.avail_out=h),(r=d.inflate(u,m.Z_NO_FLUSH))===m.Z_NEED_DICT&&f&&(o="string"==typeof f?p.string2buf(f):"[object ArrayBuffer]"===_.call(f)?new Uint8Array(f):f,r=d.inflateSetDictionary(this.strm,o)),r===m.Z_BUF_ERROR&&!0===l&&(r=m.Z_OK,l=!1),r!==m.Z_STREAM_END&&r!==m.Z_OK)return this.onEnd(r),!(this.ended=!0);u.next_out&&(0!==u.avail_out&&r!==m.Z_STREAM_END&&(0!==u.avail_in||n!==m.Z_FINISH&&n!==m.Z_SYNC_FLUSH)||("string"===this.options.to?(i=p.utf8border(u.output,u.next_out),s=u.next_out-i,a=p.buf2string(u.output,i),u.next_out=s,u.avail_out=h-s,s&&c.arraySet(u.output,u.output,i,s,0),this.onData(a)):this.onData(c.shrinkBuf(u.output,u.next_out)))),0===u.avail_in&&0===u.avail_out&&(l=!0);}while((0<u.avail_in||0===u.avail_out)&&r!==m.Z_STREAM_END);return r===m.Z_STREAM_END&&(n=m.Z_FINISH),n===m.Z_FINISH?(r=d.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===m.Z_OK):n!==m.Z_SYNC_FLUSH||(this.onEnd(m.Z_OK),!(u.avail_out=0))},a.prototype.onData=function(e){this.chunks.push(e);},a.prototype.onEnd=function(e){e===m.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=c.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},r.Inflate=a,r.inflate=o,r.inflateRaw=function(e,t){return (t=t||{}).raw=!0,o(e,t)},r.ungzip=o;},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(e,t,r){var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var n in r)r.hasOwnProperty(n)&&(e[n]=r[n]);}}return e},r.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var i={arraySet:function(e,t,r,n,i){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+n),i);else for(var s=0;s<n;s++)e[i+s]=t[r+s];},flattenChunks:function(e){var t,r,n,i,s,a;for(t=n=0,r=e.length;t<r;t++)n+=e[t].length;for(a=new Uint8Array(n),t=i=0,r=e.length;t<r;t++)s=e[t],a.set(s,i),i+=s.length;return a}},s={arraySet:function(e,t,r,n,i){for(var s=0;s<n;s++)e[i+s]=t[r+s];},flattenChunks:function(e){return [].concat.apply([],e)}};r.setTyped=function(e){e?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,i)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,s));},r.setTyped(n);},{}],42:[function(e,t,r){var u=e("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0]);}catch(e){i=!1;}try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(e){s=!1;}for(var h=new u.Buf8(256),n=0;n<256;n++)h[n]=252<=n?6:248<=n?5:240<=n?4:224<=n?3:192<=n?2:1;function f(e,t){if(t<65537&&(e.subarray&&s||!e.subarray&&i))return String.fromCharCode.apply(null,u.shrinkBuf(e,t));for(var r="",n=0;n<t;n++)r+=String.fromCharCode(e[n]);return r}h[254]=h[254]=1,r.string2buf=function(e){var t,r,n,i,s,a=e.length,o=0;for(i=0;i<a;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),o+=r<128?1:r<2048?2:r<65536?3:4;for(t=new u.Buf8(o),i=s=0;s<o;i++)55296==(64512&(r=e.charCodeAt(i)))&&i+1<a&&56320==(64512&(n=e.charCodeAt(i+1)))&&(r=65536+(r-55296<<10)+(n-56320),i++),r<128?t[s++]=r:(r<2048?t[s++]=192|r>>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return f(e,e.length)},r.binstring2buf=function(e){for(var t=new u.Buf8(e.length),r=0,n=t.length;r<n;r++)t[r]=e.charCodeAt(r);return t},r.buf2string=function(e,t){var r,n,i,s,a=t||e.length,o=new Array(2*a);for(r=n=0;r<a;)if((i=e[r++])<128)o[n++]=i;else if(4<(s=h[i]))o[n++]=65533,r+=s-1;else {for(i&=2===s?31:3===s?15:7;1<s&&r<a;)i=i<<6|63&e[r++],s--;1<s?o[n++]=65533:i<65536?o[n++]=i:(i-=65536,o[n++]=55296|i>>10&1023,o[n++]=56320|1023&i);}return f(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+h[e[r]]>t?r:t};},{"./common":41}],43:[function(e,t,r){t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3<r?2e3:r;s=s+(i=i+t[n++]|0)|0,--a;);i%=65521,s%=65521;}return i|s<<16|0};},{}],44:[function(e,t,r){t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};},{}],45:[function(e,t,r){var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t[a])];return -1^e};},{}],46:[function(e,t,r){var u,d=e("../utils/common"),h=e("./trees"),c=e("./adler32"),p=e("./crc32"),n=e("./messages"),f=0,l=0,m=-2,i=2,_=8,s=286,a=30,o=19,g=2*s+1,v=15,b=3,w=258,y=w+b+1,k=42,x=113;function S(e,t){return e.msg=n[t],t}function z(e){return (e<<1)-(4<e?9:0)}function E(e){for(var t=e.length;0<=--t;)e[t]=0;}function C(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(d.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function A(e,t){h._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,C(e.strm);}function I(e,t){e.pending_buf[e.pending++]=t;}function O(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function B(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,u=e.strstart>e.w_size-y?e.strstart-(e.w_size-y):0,h=e.window,f=e.w_mask,l=e.prev,d=e.strstart+w,c=h[s+a-1],p=h[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(h[(r=t)+a]===p&&h[r+a-1]===c&&h[r]===h[s]&&h[++r]===h[s+1]){s+=2,r++;do{}while(h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&h[++s]===h[++r]&&s<d);if(n=w-(d-s),s=d-w,a<n){if(e.match_start=t,o<=(a=n))break;c=h[s+a-1],p=h[s+a];}}}while((t=l[t&f])>u&&0!=--i);return a<=e.lookahead?a:e.lookahead}function T(e){var t,r,n,i,s,a,o,u,h,f,l=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=l+(l-y)){for(d.arraySet(e.window,e.window,l,l,0),e.match_start-=l,e.strstart-=l,e.block_start-=l,t=r=e.hash_size;n=e.head[--t],e.head[t]=l<=n?n-l:0,--r;);for(t=r=l;n=e.prev[--t],e.prev[t]=l<=n?n-l:0,--r;);i+=l;}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,u=e.strstart+e.lookahead,f=void 0,(h=i)<(f=a.avail_in)&&(f=h),r=0===f?0:(a.avail_in-=f,d.arraySet(o,a.input,a.next_in,f,u),1===a.state.wrap?a.adler=c(a.adler,o,f,u):2===a.state.wrap&&(a.adler=p(a.adler,o,f,u)),a.next_in+=f,a.total_in+=f,f),e.lookahead+=r,e.lookahead+e.insert>=b)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<<e.hash_shift^e.window[s+1])&e.hash_mask;e.insert&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[s+b-1])&e.hash_mask,e.prev[s&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=s,s++,e.insert--,!(e.lookahead+e.insert<b)););}while(e.lookahead<y&&0!==e.strm.avail_in)}function R(e,t){for(var r,n;;){if(e.lookahead<y){if(T(e),e.lookahead<y&&t===f)return 1;if(0===e.lookahead)break}if(r=0,e.lookahead>=b&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+b-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!==r&&e.strstart-r<=e.w_size-y&&(e.match_length=B(e,r)),e.match_length>=b)if(n=h._tr_tally(e,e.strstart-e.match_start,e.match_length-b),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=b){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+b-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart,0!=--e.match_length;);e.strstart++;}else e.strstart+=e.match_length,e.match_length=0,e.ins_h=e.window[e.strstart],e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+1])&e.hash_mask;else n=h._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++;if(n&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=e.strstart<b-1?e.strstart:b-1,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}function D(e,t){for(var r,n,i;;){if(e.lookahead<y){if(T(e),e.lookahead<y&&t===f)return 1;if(0===e.lookahead)break}if(r=0,e.lookahead>=b&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+b-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),e.prev_length=e.match_length,e.prev_match=e.match_start,e.match_length=b-1,0!==r&&e.prev_length<e.max_lazy_match&&e.strstart-r<=e.w_size-y&&(e.match_length=B(e,r),e.match_length<=5&&(1===e.strategy||e.match_length===b&&4096<e.strstart-e.match_start)&&(e.match_length=b-1)),e.prev_length>=b&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-b,n=h._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-b),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<<e.hash_shift^e.window[e.strstart+b-1])&e.hash_mask,r=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!=--e.prev_length;);if(e.match_available=0,e.match_length=b-1,e.strstart++,n&&(A(e,!1),0===e.strm.avail_out))return 1}else if(e.match_available){if((n=h._tr_tally(e,0,e.window[e.strstart-1]))&&A(e,!1),e.strstart++,e.lookahead--,0===e.strm.avail_out)return 1}else e.match_available=1,e.strstart++,e.lookahead--;}return e.match_available&&(n=h._tr_tally(e,0,e.window[e.strstart-1]),e.match_available=0),e.insert=e.strstart<b-1?e.strstart:b-1,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}function F(e,t,r,n,i){this.good_length=e,this.max_lazy=t,this.nice_length=r,this.max_chain=n,this.func=i;}function N(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=_,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new d.Buf16(2*g),this.dyn_dtree=new d.Buf16(2*(2*a+1)),this.bl_tree=new d.Buf16(2*(2*o+1)),E(this.dyn_ltree),E(this.dyn_dtree),E(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new d.Buf16(v+1),this.heap=new d.Buf16(2*s+1),E(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new d.Buf16(2*s+1),E(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0;}function U(e){var t;return e&&e.state?(e.total_in=e.total_out=0,e.data_type=i,(t=e.state).pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=t.wrap?k:x,e.adler=2===t.wrap?0:1,t.last_flush=f,h._tr_init(t),l):S(e,m)}function P(e){var t,r=U(e);return r===l&&((t=e.state).window_size=2*t.w_size,E(t.head),t.max_lazy_match=u[t.level].max_lazy,t.good_match=u[t.level].good_length,t.nice_match=u[t.level].nice_length,t.max_chain_length=u[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=b-1,t.match_available=0,t.ins_h=0),r}function L(e,t,r,n,i,s){if(!e)return m;var a=1;if(-1===t&&(t=6),n<0?(a=0,n=-n):15<n&&(a=2,n-=16),i<1||9<i||r!==_||n<8||15<n||t<0||9<t||s<0||4<s)return S(e,m);8===n&&(n=9);var o=new N;return (e.state=o).strm=e,o.wrap=a,o.gzhead=null,o.w_bits=n,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=i+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+b-1)/b),o.window=new d.Buf8(2*o.w_size),o.head=new d.Buf16(o.hash_size),o.prev=new d.Buf16(o.w_size),o.lit_bufsize=1<<i+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new d.Buf8(o.pending_buf_size),o.d_buf=1*o.lit_bufsize,o.l_buf=3*o.lit_bufsize,o.level=t,o.strategy=s,o.method=r,P(e)}u=[new F(0,0,0,0,function(e,t){var r=65535;for(r>e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(T(e),0===e.lookahead&&t===f)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,A(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-y&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(A(e,!1),e.strm.avail_out),1)}),new F(4,4,8,4,R),new F(4,5,16,8,R),new F(4,6,32,32,R),new F(4,4,16,16,D),new F(8,16,32,32,D),new F(8,16,128,128,D),new F(8,32,128,256,D),new F(32,128,258,1024,D),new F(32,258,258,4096,D)],r.deflateInit=function(e,t){return L(e,t,_,15,8,0)},r.deflateInit2=L,r.deflateReset=P,r.deflateResetKeep=U,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?m:(e.state.gzhead=t,l):m},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5<t||t<0)return e?S(e,m):m;if(n=e.state,!e.output||!e.input&&0!==e.avail_in||666===n.status&&4!==t)return S(e,0===e.avail_out?-5:m);if(n.strm=e,r=n.last_flush,n.last_flush=t,n.status===k)if(2===n.wrap)e.adler=0,I(n,31),I(n,139),I(n,8),n.gzhead?(I(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),I(n,255&n.gzhead.time),I(n,n.gzhead.time>>8&255),I(n,n.gzhead.time>>16&255),I(n,n.gzhead.time>>24&255),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(I(n,255&n.gzhead.extra.length),I(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(I(n,0),I(n,0),I(n,0),I(n,0),I(n,0),I(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),I(n,3),n.status=x);else {var a=_+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=x,O(n,a),0!==n.strstart&&(O(n,e.adler>>>16),O(n,65535&e.adler)),e.adler=1;}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending!==n.pending_buf_size));)I(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73);}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindex<n.gzhead.name.length?255&n.gzhead.name.charCodeAt(n.gzindex++):0,I(n,s);}while(0!==s);n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91);}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),C(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindex<n.gzhead.comment.length?255&n.gzhead.comment.charCodeAt(n.gzindex++):0,I(n,s);}while(0!==s);n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103);}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&C(e),n.pending+2<=n.pending_buf_size&&(I(n,255&e.adler),I(n,e.adler>>8&255),e.adler=0,n.status=x)):n.status=x),0!==n.pending){if(C(e),0===e.avail_out)return n.last_flush=-1,l}else if(0===e.avail_in&&z(t)<=z(r)&&4!==t)return S(e,-5);if(666===n.status&&0!==e.avail_in)return S(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==f&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(T(e),0===e.lookahead)){if(t===f)return 1;break}if(e.match_length=0,r=h._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=w){if(T(e),e.lookahead<=w&&t===f)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=b&&0<e.strstart&&(n=a[i=e.strstart-1])===a[++i]&&n===a[++i]&&n===a[++i]){s=e.strstart+w;do{}while(n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&i<s);e.match_length=w-(s-i),e.match_length>e.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=b?(r=h._tr_tally(e,1,e.match_length-b),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=h._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(A(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(A(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(A(e,!1),0===e.strm.avail_out)?1:2}(n,t):u[n.level].func(n,t);if(3!==o&&4!==o||(n.status=666),1===o||3===o)return 0===e.avail_out&&(n.last_flush=-1),l;if(2===o&&(1===t?h._tr_align(n):5!==t&&(h._tr_stored_block(n,0,0,!1),3===t&&(E(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),C(e),0===e.avail_out))return n.last_flush=-1,l}return 4!==t?l:n.wrap<=0?1:(2===n.wrap?(I(n,255&e.adler),I(n,e.adler>>8&255),I(n,e.adler>>16&255),I(n,e.adler>>24&255),I(n,255&e.total_in),I(n,e.total_in>>8&255),I(n,e.total_in>>16&255),I(n,e.total_in>>24&255)):(O(n,e.adler>>>16),O(n,65535&e.adler)),C(e),0<n.wrap&&(n.wrap=-n.wrap),0!==n.pending?l:1)},r.deflateEnd=function(e){var t;return e&&e.state?(t=e.state.status)!==k&&69!==t&&73!==t&&91!==t&&103!==t&&t!==x&&666!==t?S(e,m):(e.state=null,t===x?S(e,-3):l):m},r.deflateSetDictionary=function(e,t){var r,n,i,s,a,o,u,h,f=t.length;if(!e||!e.state)return m;if(2===(s=(r=e.state).wrap)||1===s&&r.status!==k||r.lookahead)return m;for(1===s&&(e.adler=c(e.adler,t,f,0)),r.wrap=0,f>=r.w_size&&(0===s&&(E(r.head),r.strstart=0,r.block_start=0,r.insert=0),h=new d.Buf8(r.w_size),d.arraySet(h,t,f-r.w_size,r.w_size,0),t=h,f=r.w_size),a=e.avail_in,o=e.next_in,u=e.input,e.avail_in=f,e.next_in=0,e.input=t,T(r);r.lookahead>=b;){for(n=r.strstart,i=r.lookahead-(b-1);r.ins_h=(r.ins_h<<r.hash_shift^r.window[n+b-1])&r.hash_mask,r.prev[n&r.w_mask]=r.head[r.ins_h],r.head[r.ins_h]=n,n++,--i;);r.strstart=n,r.lookahead=b-1,T(r);}return r.strstart+=r.lookahead,r.block_start=r.strstart,r.insert=r.lookahead,r.lookahead=0,r.match_length=r.prev_length=b-1,r.match_available=0,e.next_in=o,e.input=u,e.avail_in=a,r.wrap=s,l},r.deflateInfo="pako deflate (from Nodeca project)";},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(e,t,r){t.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1;};},{}],48:[function(e,t,r){t.exports=function(e,t){var r,n,i,s,a,o,u,h,f,l,d,c,p,m,_,g,v,b,w,y,k,x,S,z,E;r=e.state,n=e.next_in,z=e.input,i=n+(e.avail_in-5),s=e.next_out,E=e.output,a=s-(t-e.avail_out),o=s+(e.avail_out-257),u=r.dmax,h=r.wsize,f=r.whave,l=r.wnext,d=r.window,c=r.hold,p=r.bits,m=r.lencode,_=r.distcode,g=(1<<r.lenbits)-1,v=(1<<r.distbits)-1;e:do{p<15&&(c+=z[n++]<<p,p+=8,c+=z[n++]<<p,p+=8),b=m[c&g];t:for(;;){if(c>>>=w=b>>>24,p-=w,0==(w=b>>>16&255))E[s++]=65535&b;else {if(!(16&w)){if(0==(64&w)){b=m[(65535&b)+(c&(1<<w)-1)];continue t}if(32&w){r.mode=12;break e}e.msg="invalid literal/length code",r.mode=30;break e}y=65535&b,(w&=15)&&(p<w&&(c+=z[n++]<<p,p+=8),y+=c&(1<<w)-1,c>>>=w,p-=w),p<15&&(c+=z[n++]<<p,p+=8,c+=z[n++]<<p,p+=8),b=_[c&v];r:for(;;){if(c>>>=w=b>>>24,p-=w,!(16&(w=b>>>16&255))){if(0==(64&w)){b=_[(65535&b)+(c&(1<<w)-1)];continue r}e.msg="invalid distance code",r.mode=30;break e}if(k=65535&b,p<(w&=15)&&(c+=z[n++]<<p,(p+=8)<w&&(c+=z[n++]<<p,p+=8)),u<(k+=c&(1<<w)-1)){e.msg="invalid distance too far back",r.mode=30;break e}if(c>>>=w,p-=w,(w=s-a)<k){if(f<(w=k-w)&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(S=d,(x=0)===l){if(x+=h-w,w<y){for(y-=w;E[s++]=d[x++],--w;);x=s-k,S=E;}}else if(l<w){if(x+=h+l-w,(w-=l)<y){for(y-=w;E[s++]=d[x++],--w;);if(x=0,l<y){for(y-=w=l;E[s++]=d[x++],--w;);x=s-k,S=E;}}}else if(x+=l-w,w<y){for(y-=w;E[s++]=d[x++],--w;);x=s-k,S=E;}for(;2<y;)E[s++]=S[x++],E[s++]=S[x++],E[s++]=S[x++],y-=3;y&&(E[s++]=S[x++],1<y&&(E[s++]=S[x++]));}else {for(x=s-k;E[s++]=E[x++],E[s++]=E[x++],E[s++]=E[x++],2<(y-=3););y&&(E[s++]=E[x++],1<y&&(E[s++]=E[x++]));}break}}break}}while(n<i&&s<o);n-=y=p>>3,c&=(1<<(p-=y<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n<i?i-n+5:5-(n-i),e.avail_out=s<o?o-s+257:257-(s-o),r.hold=c,r.bits=p;};},{}],49:[function(e,t,r){var I=e("../utils/common"),O=e("./adler32"),B=e("./crc32"),T=e("./inffast"),R=e("./inftrees"),D=1,F=2,N=0,U=-2,P=1,n=852,i=592;function L(e){return (e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function u(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15<t)?U:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,o(e))):U}function h(e,t){var r,n;return e?(n=new s,(e.state=n).window=null,(r=u(e,t))!==N&&(e.state=null),r):U}var f,l,d=!0;function j(e){if(d){var t;for(f=new I.Buf32(512),l=new I.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(R(D,e.lens,0,288,f,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;R(F,e.lens,0,32,l,0,e.work,{bits:5}),d=!1;}e.lencode=f,e.lenbits=9,e.distcode=l,e.distbits=5;}function Z(e,t,r,n){var i,s=e.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new I.Buf8(s.wsize)),n>=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=i))),0}r.inflateReset=o,r.inflateReset2=u,r.inflateResetKeep=a,r.inflateInit=function(e){return h(e,15)},r.inflateInit2=h,r.inflate=function(e,t){var r,n,i,s,a,o,u,h,f,l,d,c,p,m,_,g,v,b,w,y,k,x,S,z,E=0,C=new I.Buf8(4),A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return U;12===(r=e.state).mode&&(r.mode=13),a=e.next_out,i=e.output,u=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,h=r.hold,f=r.bits,l=o,d=u,x=N;e:for(;;)switch(r.mode){case P:if(0===r.wrap){r.mode=13;break}for(;f<16;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(2&r.wrap&&35615===h){C[r.check=0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0),f=h=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&h)<<8)+(h>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&h)){e.msg="unknown compression method",r.mode=30;break}if(f-=4,k=8+(15&(h>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<<k,e.adler=r.check=1,r.mode=512&h?10:12,f=h=0;break;case 2:for(;f<16;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(r.flags=h,8!=(255&r.flags)){e.msg="unknown compression method",r.mode=30;break}if(57344&r.flags){e.msg="unknown header flags set",r.mode=30;break}r.head&&(r.head.text=h>>8&1),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0)),f=h=0,r.mode=3;case 3:for(;f<32;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.head&&(r.head.time=h),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,C[2]=h>>>16&255,C[3]=h>>>24&255,r.check=B(r.check,C,4,0)),f=h=0,r.mode=4;case 4:for(;f<16;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.head&&(r.head.xflags=255&h,r.head.os=h>>8),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0)),f=h=0,r.mode=5;case 5:if(1024&r.flags){for(;f<16;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.length=h,r.head&&(r.head.extra_len=h),512&r.flags&&(C[0]=255&h,C[1]=h>>>8&255,r.check=B(r.check,C,2,0)),f=h=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,c,k)),512&r.flags&&(r.check=B(r.check,n,c,s)),o-=c,s+=c,r.length-=c),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(c=0;k=n[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,n,c,s)),o-=c,s+=c,k)break e}else r.head&&(r.head.name=null);r.length=0,r.mode=8;case 8:if(4096&r.flags){if(0===o)break e;for(c=0;k=n[s+c++],r.head&&k&&r.length<65536&&(r.head.comment+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,n,c,s)),o-=c,s+=c,k)break e}else r.head&&(r.head.comment=null);r.mode=9;case 9:if(512&r.flags){for(;f<16;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(h!==(65535&r.check)){e.msg="header crc mismatch",r.mode=30;break}f=h=0;}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;f<32;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}e.adler=r.check=L(h),f=h=0,r.mode=11;case 11:if(0===r.havedict)return e.next_out=a,e.avail_out=u,e.next_in=s,e.avail_in=o,r.hold=h,r.bits=f,2;e.adler=r.check=1,r.mode=12;case 12:if(5===t||6===t)break e;case 13:if(r.last){h>>>=7&f,f-=7&f,r.mode=27;break}for(;f<3;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}switch(r.last=1&h,f-=1,3&(h>>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;h>>>=2,f-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30;}h>>>=2,f-=2;break;case 14:for(h>>>=7&f,f-=7&f;f<32;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if((65535&h)!=(h>>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&h,f=h=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(c=r.length){if(o<c&&(c=o),u<c&&(c=u),0===c)break e;I.arraySet(i,n,s,c,a),o-=c,s+=c,u-=c,a+=c,r.length-=c;break}r.mode=12;break;case 17:for(;f<14;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(r.nlen=257+(31&h),h>>>=5,f-=5,r.ndist=1+(31&h),h>>>=5,f-=5,r.ncode=4+(15&h),h>>>=4,f-=4,286<r.nlen||30<r.ndist){e.msg="too many length or distance symbols",r.mode=30;break}r.have=0,r.mode=18;case 18:for(;r.have<r.ncode;){for(;f<3;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.lens[A[r.have++]]=7&h,h>>>=3,f-=3;}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=R(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have<r.nlen+r.ndist;){for(;g=(E=r.lencode[h&(1<<r.lenbits)-1])>>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(v<16)h>>>=_,f-=_,r.lens[r.have++]=v;else {if(16===v){for(z=_+2;f<z;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(h>>>=_,f-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&h),h>>>=2,f-=2;}else if(17===v){for(z=_+3;f<z;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}f-=_,k=0,c=3+(7&(h>>>=_)),h>>>=3,f-=3;}else {for(z=_+7;f<z;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}f-=_,k=0,c=11+(127&(h>>>=_)),h>>>=7,f-=7;}if(r.have+c>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k;}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=R(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=R(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=u){e.next_out=a,e.avail_out=u,e.next_in=s,e.avail_in=o,r.hold=h,r.bits=f,T(e,d),a=e.next_out,i=e.output,u=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,h=r.hold,f=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(E=r.lencode[h&(1<<r.lenbits)-1])>>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(g&&0==(240&g)){for(b=_,w=g,y=v;g=(E=r.lencode[y+((h&(1<<b+w)-1)>>b)])>>>16&255,v=65535&E,!(b+(_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}h>>>=b,f-=b,r.back+=b;}if(h>>>=_,f-=_,r.back+=_,r.length=v,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;f<z;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.length+=h&(1<<r.extra)-1,h>>>=r.extra,f-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;g=(E=r.distcode[h&(1<<r.distbits)-1])>>>16&255,v=65535&E,!((_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(0==(240&g)){for(b=_,w=g,y=v;g=(E=r.distcode[y+((h&(1<<b+w)-1)>>b)])>>>16&255,v=65535&E,!(b+(_=E>>>24)<=f);){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}h>>>=b,f-=b,r.back+=b;}if(h>>>=_,f-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=v,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;f<z;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}r.offset+=h&(1<<r.extra)-1,h>>>=r.extra,f-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===u)break e;if(c=d-u,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window;}else m=i,p=a-r.offset,c=r.length;for(u<c&&(c=u),u-=c,r.length-=c;i[a++]=m[p++],--c;);0===r.length&&(r.mode=21);break;case 26:if(0===u)break e;i[a++]=r.length,u--,r.mode=21;break;case 27:if(r.wrap){for(;f<32;){if(0===o)break e;o--,h|=n[s++]<<f,f+=8;}if(d-=u,e.total_out+=d,r.total+=d,d&&(e.adler=r.check=r.flags?B(r.check,i,d,a-d):O(r.check,i,d,a-d)),d=u,(r.flags?h:L(h))!==r.check){e.msg="incorrect data check",r.mode=30;break}f=h=0;}r.mode=28;case 28:if(r.wrap&&r.flags){for(;f<32;){if(0===o)break e;o--,h+=n[s++]<<f,f+=8;}if(h!==(4294967295&r.total)){e.msg="incorrect length check",r.mode=30;break}f=h=0;}r.mode=29;case 29:x=1;break e;case 30:x=-3;break e;case 31:return -4;case 32:default:return U}return e.next_out=a,e.avail_out=u,e.next_in=s,e.avail_in=o,r.hold=h,r.bits=f,(r.wsize||d!==e.avail_out&&r.mode<30&&(r.mode<27||4!==t))&&Z(e,e.output,e.next_out,d-e.avail_out)?(r.mode=31,-4):(l-=e.avail_in,d-=e.avail_out,e.total_in+=l,e.total_out+=d,r.total+=d,r.wrap&&d&&(e.adler=r.check=r.flags?B(r.check,i,d,e.next_out-d):O(r.check,i,d,e.next_out-d)),e.data_type=r.bits+(r.last?64:0)+(12===r.mode?128:0)+(20===r.mode||15===r.mode?256:0),(0==l&&0===d||4===t)&&x===N&&(x=-5),x)},r.inflateEnd=function(e){if(!e||!e.state)return U;var t=e.state;return t.window&&(t.window=null),e.state=null,N},r.inflateGetHeader=function(e,t){var r;return e&&e.state?0==(2&(r=e.state).wrap)?U:((r.head=t).done=!1,N):U},r.inflateSetDictionary=function(e,t){var r,n=t.length;return e&&e.state?0!==(r=e.state).wrap&&11!==r.mode?U:11===r.mode&&O(1,t,n,0)!==r.check?-3:Z(e,t,n,n)?(r.mode=31,-4):(r.havedict=1,N):U},r.inflateInfo="pako inflate (from Nodeca project)";},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(e,t,r){var D=e("../utils/common"),F=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],N=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],U=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],P=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];t.exports=function(e,t,r,n,i,s,a,o){var u,h,f,l,d,c,p,m,_,g=o.bits,v=0,b=0,w=0,y=0,k=0,x=0,S=0,z=0,E=0,C=0,A=null,I=0,O=new D.Buf16(16),B=new D.Buf16(16),T=null,R=0;for(v=0;v<=15;v++)O[v]=0;for(b=0;b<n;b++)O[t[r+b]]++;for(k=g,y=15;1<=y&&0===O[y];y--);if(y<k&&(k=y),0===y)return i[s++]=20971520,i[s++]=20971520,o.bits=1,0;for(w=1;w<y&&0===O[w];w++);for(k<w&&(k=w),v=z=1;v<=15;v++)if(z<<=1,(z-=O[v])<0)return -1;if(0<z&&(0===e||1!==y))return -1;for(B[1]=0,v=1;v<15;v++)B[v+1]=B[v]+O[v];for(b=0;b<n;b++)0!==t[r+b]&&(a[B[t[r+b]]++]=b);if(c=0===e?(A=T=a,19):1===e?(A=F,I-=257,T=N,R-=257,256):(A=U,T=P,-1),v=w,d=s,S=b=C=0,f=-1,l=(E=1<<(x=k))-1,1===e&&852<E||2===e&&592<E)return 1;for(;;){for(p=v-S,_=a[b]<c?(m=0,a[b]):a[b]>c?(m=T[R+a[b]],A[I+a[b]]):(m=96,0),u=1<<v-S,w=h=1<<x;i[d+(C>>S)+(h-=u)]=p<<24|m<<16|_|0,0!==h;);for(u=1<<v-1;C&u;)u>>=1;if(0!==u?(C&=u-1,C+=u):C=0,b++,0==--O[v]){if(v===y)break;v=t[r+a[b]];}if(k<v&&(C&l)!==f){for(0===S&&(S=k),d+=w,z=1<<(x=v-S);x+S<y&&!((z-=O[x+S])<=0);)x++,z<<=1;if(E+=1<<x,1===e&&852<E||2===e&&592<E)return 1;i[f=C&l]=k<<24|x<<16|d-s|0;}}return 0!==C&&(i[d+C]=v-S<<24|64<<16|0),o.bits=k,0};},{"../utils/common":41}],51:[function(e,t,r){t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"};},{}],52:[function(e,t,r){var o=e("../utils/common");function n(e){for(var t=e.length;0<=--t;)e[t]=0;}var _=15,i=16,u=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],h=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],f=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],l=new Array(576);n(l);var d=new Array(60);n(d);var c=new Array(512);n(c);var p=new Array(256);n(p);var m=new Array(29);n(m);var g,v,b,w=new Array(30);function y(e,t,r,n,i){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=n,this.max_length=i,this.has_stree=e&&e.length;}function s(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t;}function k(e){return e<256?c[e]:c[256+(e>>>7)]}function x(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function S(e,t,r){e.bi_valid>i-r?(e.bi_buf|=t<<e.bi_valid&65535,x(e,e.bi_buf),e.bi_buf=t>>i-e.bi_valid,e.bi_valid+=r-i):(e.bi_buf|=t<<e.bi_valid&65535,e.bi_valid+=r);}function z(e,t,r){S(e,r[2*t],r[2*t+1]);}function E(e,t){for(var r=0;r|=1&e,e>>>=1,r<<=1,0<--t;);return r>>>1}function C(e,t,r){var n,i,s=new Array(_+1),a=0;for(n=1;n<=_;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=E(s[o]++,o));}}function A(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0;}function I(e){8<e.bi_valid?x(e,e.bi_buf):0<e.bi_valid&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0;}function O(e,t,r,n){var i=2*t,s=2*r;return e[i]<e[s]||e[i]===e[s]&&n[t]<=n[r]}function B(e,t,r){for(var n=e.heap[r],i=r<<1;i<=e.heap_len&&(i<e.heap_len&&O(t,e.heap[i+1],e.heap[i],e.depth)&&i++,!O(t,n,e.heap[i],e.depth));)e.heap[r]=e.heap[i],r=i,i<<=1;e.heap[r]=n;}function T(e,t,r){var n,i,s,a,o=0;if(0!==e.last_lit)for(;n=e.pending_buf[e.d_buf+2*o]<<8|e.pending_buf[e.d_buf+2*o+1],i=e.pending_buf[e.l_buf+o],o++,0===n?z(e,i,t):(z(e,(s=p[i])+256+1,t),0!==(a=u[s])&&S(e,i-=m[s],a),z(e,s=k(--n),r),0!==(a=h[s])&&S(e,n-=w[s],a)),o<e.last_lit;);z(e,256,t);}function R(e,t){var r,n,i,s=t.dyn_tree,a=t.stat_desc.static_tree,o=t.stat_desc.has_stree,u=t.stat_desc.elems,h=-1;for(e.heap_len=0,e.heap_max=573,r=0;r<u;r++)0!==s[2*r]?(e.heap[++e.heap_len]=h=r,e.depth[r]=0):s[2*r+1]=0;for(;e.heap_len<2;)s[2*(i=e.heap[++e.heap_len]=h<2?++h:0)]=1,e.depth[i]=0,e.opt_len--,o&&(e.static_len-=a[2*i+1]);for(t.max_code=h,r=e.heap_len>>1;1<=r;r--)B(e,s,r);for(i=u;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],B(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,B(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,u=t.dyn_tree,h=t.max_code,f=t.stat_desc.static_tree,l=t.stat_desc.has_stree,d=t.stat_desc.extra_bits,c=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=_;s++)e.bl_count[s]=0;for(u[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)p<(s=u[2*u[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),u[2*n+1]=s,h<n||(e.bl_count[s]++,a=0,c<=n&&(a=d[n-c]),o=u[2*n],e.opt_len+=o*(s+a),l&&(e.static_len+=o*(f[2*n+1]+a)));if(0!==m){do{for(s=p-1;0===e.bl_count[s];)s--;e.bl_count[s]--,e.bl_count[s+1]+=2,e.bl_count[p]--,m-=2;}while(0<m);for(s=p;0!==s;s--)for(n=e.bl_count[s];0!==n;)h<(i=e.heap[--r])||(u[2*i+1]!==s&&(e.opt_len+=(s-u[2*i+1])*u[2*i],u[2*i+1]=s),n--);}}(e,t),C(s,h,e.bl_count);}function D(e,t,r){var n,i,s=-1,a=t[1],o=0,u=7,h=4;for(0===a&&(u=138,h=3),t[2*(r+1)+1]=65535,n=0;n<=r;n++)i=a,a=t[2*(n+1)+1],++o<u&&i===a||(o<h?e.bl_tree[2*i]+=o:0!==i?(i!==s&&e.bl_tree[2*i]++,e.bl_tree[32]++):o<=10?e.bl_tree[34]++:e.bl_tree[36]++,s=i,h=(o=0)===a?(u=138,3):i===a?(u=6,3):(u=7,4));}function F(e,t,r){var n,i,s=-1,a=t[1],o=0,u=7,h=4;for(0===a&&(u=138,h=3),n=0;n<=r;n++)if(i=a,a=t[2*(n+1)+1],!(++o<u&&i===a)){if(o<h)for(;z(e,i,e.bl_tree),0!=--o;);else 0!==i?(i!==s&&(z(e,i,e.bl_tree),o--),z(e,16,e.bl_tree),S(e,o-3,2)):o<=10?(z(e,17,e.bl_tree),S(e,o-3,3)):(z(e,18,e.bl_tree),S(e,o-11,7));s=i,h=(o=0)===a?(u=138,3):i===a?(u=6,3):(u=7,4);}}n(w);var N=!1;function U(e,t,r,n){var i,s,a;S(e,0+(n?1:0),3),s=t,a=r,I(i=e),x(i,a),x(i,~a),o.arraySet(i.pending_buf,i.window,s,a,i.pending),i.pending+=a;}r._tr_init=function(e){N||(function(){var e,t,r,n,i,s=new Array(_+1);for(n=r=0;n<28;n++)for(m[n]=r,e=0;e<1<<u[n];e++)p[r++]=n;for(p[r-1]=n,n=i=0;n<16;n++)for(w[n]=i,e=0;e<1<<h[n];e++)c[i++]=n;for(i>>=7;n<30;n++)for(w[n]=i<<7,e=0;e<1<<h[n]-7;e++)c[256+i++]=n;for(t=0;t<=_;t++)s[t]=0;for(e=0;e<=143;)l[2*e+1]=8,e++,s[8]++;for(;e<=255;)l[2*e+1]=9,e++,s[9]++;for(;e<=279;)l[2*e+1]=7,e++,s[7]++;for(;e<=287;)l[2*e+1]=8,e++,s[8]++;for(C(l,287,s),e=0;e<30;e++)d[2*e+1]=5,d[2*e]=E(e,5);g=new y(l,u,257,286,_),v=new y(d,h,0,30,_),b=new y(new Array(0),a,0,19,7);}(),N=!0),e.l_desc=new s(e.dyn_ltree,g),e.d_desc=new s(e.dyn_dtree,v),e.bl_desc=new s(e.bl_tree,b),e.bi_buf=0,e.bi_valid=0,A(e);},r._tr_stored_block=U,r._tr_flush_block=function(e,t,r,n){var i,s,a=0;0<e.level?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),R(e,e.l_desc),R(e,e.d_desc),a=function(e){var t;for(D(e,e.dyn_ltree,e.l_desc.max_code),D(e,e.dyn_dtree,e.d_desc.max_code),R(e,e.bl_desc),t=18;3<=t&&0===e.bl_tree[2*f[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||s===i?(S(e,2+(n?1:0),3),T(e,l,d)):(S(e,4+(n?1:0),3),function(e,t,r,n){var i;for(S(e,t-257,5),S(e,r-1,5),S(e,n-4,4),i=0;i<n;i++)S(e,e.bl_tree[2*f[i]+1],3);F(e,e.dyn_ltree,t-1),F(e,e.dyn_dtree,r-1);}(e,e.l_desc.max_code+1,e.d_desc.max_code+1,a+1),T(e,e.dyn_ltree,e.dyn_dtree)),A(e),n&&I(e);},r._tr_tally=function(e,t,r){return e.pending_buf[e.d_buf+2*e.last_lit]=t>>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(p[r]+256+1)]++,e.dyn_dtree[2*k(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){var t;S(e,2,3),z(e,256,l),16===(t=e).bi_valid?(x(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8);};},{"../utils/common":41}],53:[function(e,t,r){t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};},{}],54:[function(e,t,r){t.exports="function"==typeof setImmediate?setImmediate:function(){var e=[].slice.apply(arguments);e.splice(1,0,0),setTimeout$1.apply(null,e);};},{}]},{},[10])(10)});}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[1])(1)});}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[1])(1)});}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[1])(1)});}).call(this,void 0!==r?r:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[1])(1)});}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[1])(1)});
	JSZip=window.JSZip;
}
var JSZip$1 = JSZip;

//----------------------------------------------------------------------------
//Unpack zip to path
let zip2Path=async function(path,zipFile,dirZipName=0,tty=null,peelRoot=false,deltaTime=0){
	var zipDir,zipDirs,zipName,disk,zipData;
	let basePath,pts,diskName;
	let rootName,willPeel=false;

	async function arrayBuffer(file){
		if(file.arrayBuffer){
			return file.arrayBuffer();
		}
		return new Promise((onDone)=>{
			let reader=new FileReader();
			reader.onload=function(event) {
				let arrayBuffer = event.target.result;
				onDone(arrayBuffer);
			};
			reader.readAsArrayBuffer(file);
		});
	}
	

	pts=path.split("/");
	if(pts[0]!==""){
		throw Error("Path must be absolute.");
	}
	diskName=pts[1];
	if(!diskName){
		throw Error("Disk name error.");
	}
	if(pts.length===2){
		basePath="";
	}else {
		basePath=pts.slice(2).join("/");
	}

	
	disk=await tabFS.openDisk(diskName,0);
	if(!disk){
		throw Error("Disk open error.");
	}

	zipDirs=[];
	if(zipFile instanceof Uint8Array){
		zipData=zipFile;
		zipDir=basePath;
	}else if(zipFile instanceof ArrayBuffer){
		zipData=zipFile;
		zipDir=basePath;
	}else {
		zipData=await arrayBuffer(zipFile);
		if(dirZipName){
			zipName=zipFile.name||"";
			{
				let pos;
				pos=zipName.lastIndexOf(".");
				if(pos>0){
					zipName=zipName.substring(0,pos);
				}
			}
			zipDir=basePath+(basePath?"/":"")+zipName;
		}else {
			zipDir=basePath;
		}
	}

	async function doFiles(list){
		let filePath,i,n,path,zipObj,buf,time;
		n=list.length;
		for(i=0;i<n;i++){
			path=list[i].path;
			zipObj=list[i].zipObj;
			time=list[i].time;
			filePath=pathLib.join(zipDir,path);
			if(tty){
				tty.clearLine();
				tty.textOut("Extracting file: "+path);
			}
			buf=await zipObj.async("uint8array");
			await disk.saveFile(filePath,buf);
			if(time>0){
				await disk.setEntryInfo(filePath,{modifyTime:time+deltaTime,createTime:time+deltaTime});
			}
			/*await zipObj.async("uint8array").then((buf)=>{
				return disk.saveFile(filePath,buf);
			});*/
		}
		return true;
	}

	async function doDirs(list){
		let i,n,path;
		n=list.length;
		for(i=0;i<n;i++){
			path=list[i];
			await disk.newDir(path);
		}
		return true;
	}
	
	if(tty){
		tty.textOut("Reading zip...");
	}
	return JSZip$1.loadAsync(zipData).then(zip=>{
		let stub;
		let list=[];
		if(zip.length===1){
			let zipObj=zip[0];
			if(zipObj.dir);
			//TODO: 单个文件?
		}else {
			if(peelRoot){
				let pos;
				willPeel=true;
				//First, find root:
				zip.forEach((path,zipObj)=>{
					if(!willPeel)
						return;
					if(!rootName){
						pos=path.indexOf("/");
						if(pos<0){
							if(zipObj.dir){
								rootName=path+"/";
							}else {
								willPeel=false;
							}
						}else {
							rootName=path.substring(0,pos+1);
						}
					}else {
						if(!path.startsWith(rootName)){
							willPeel=false;
						}
					}
				});
			}
			if(willPeel && rootName){
				let peelLength;
				peelLength=rootName.length;
				zip.forEach((path,zipObj)=>{
					if(zipObj.dir){
						if(path!==rootName){
							let dirPath;
							path=path.substring(peelLength);
							dirPath=pathLib.join(zipDir,path);
							zipDirs.push(dirPath);
						}
					}else {
						path=path.substring(peelLength);
						stub={path:path,zipObj:zipObj};
						if(zipObj.date && zipObj.date.getTime){
							stub.time=Date.parse(zipObj.date).getTime();
						}
						list.push(stub);
					}
				});
			}else {
				zip.forEach((path,zipObj)=>{
					if(zipObj.dir){
						let dirPath;
						dirPath=pathLib.join(zipDir,path);
						zipDirs.push(dirPath);
					}else {
						stub={path:path,zipObj:zipObj};
						if(zipObj.date){
							try{
								stub.time=Date.parse(zipObj.date).getTime();
							}catch(err){
							}
						}
						list.push(stub);
					}
				});
			}
			return doFiles(list).then(()=>{
				doDirs(zipDirs).then(()=>{
					if(tty){
						tty.clearLine();
						tty.textOut("Extract zip done.\n");
					}
				});
			});
		}
	});
};

//----------------------------------------------------------------------------
//Unpack zip to new path, this can speed up a lot:
let zip2NewPath=async function(tgtPath,zipFile,tty=null,peelRoot=false,deltaTime=0){
	let dirEntries={};
	let pmsList=[];
	let disk,diskName,zipDir,pms,zipDirObj,dirPrefix;
	let rootName,willPeel=false;
	let nowTime=Date.now();

	async function arrayBuffer(file){
		if(file.arrayBuffer){
			return file.arrayBuffer();
		}
		return new Promise((onDone)=>{
			let reader=new FileReader();
			reader.onload=function(event) {
				let arrayBuffer = event.target.result;
				onDone(arrayBuffer);
			};
			reader.readAsArrayBuffer(file);
		});
	}

	async function parseTgtPath(){
		if(tgtPath.endsWith("/")){
			tgtPath=tgtPath.substring(tgtPath.length-1);
		}
		if(!tgtPath.startsWith("/")){
			throw Error(`Zip path ${tgtPath} is not full-path`);
		}
		let pos=tgtPath.indexOf("/",1);
		if(pos>0) {
			diskName = tgtPath.substring(1, pos);
			zipDir = tgtPath.substring(pos + 1);
			dirPrefix=zipDir+"/";
		}else {
			diskName = tgtPath.substring(1);
			zipDir = "";
			dirPrefix="";
		}
		disk = await tabFS.openDisk(diskName, true);
		zipDirObj=await get(zipDir||".",disk.dbStore);
		dirEntries[""]=zipDirObj;
	}
	
	function parsePath(path){
		let pos=path.lastIndexOf("/");
		if(pos>0){
			return [path.substring(0,pos),path.substring(pos+1)];
		}
		return ["",path];
	}
	
	function getDir(dir){
		let entry;
		entry=dirEntries[dir];
		if(!entry){
			entry={};
			dirEntries[dir]=entry;
			if(dir) {
				let [dirname, basename] = parsePath(dir);
				let upperEntry = getDir(dirname);
				let time = Date.now();
				upperEntry[basename] = { name: basename, dir: 1, createTime: time+deltaTime, modifyTime: time+deltaTime};
			}
		}
		return entry;
	}
	
	async function digestBytes(buf) {
		let hex;
		const hashBuffer = await crypto.subtle.digest('SHA-256', buf);     // hash the data
		const hashArray = Array.from(new Uint8Array(hashBuffer));          // convert buffer to byte array
		hex= hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
		return hex;
	}
	
	function writeFile(path,data,time){
		let [dirname,basename]=parsePath(path);
		let dirEntry=getDir(dirname);
		return digestBytes(data).then(byteHex=>{
			dirEntry[basename]={name:basename,dir:0,createTime:time+deltaTime,modifyTime:time+deltaTime,size:data.byteLength,modified:true,
								hash:byteHex};
			return set(dirPrefix+path,data,disk.dbStore);
		});
	}

	let zipBuf,zip,fileList=[];
	if(zipFile instanceof Uint8Array){
		zipBuf=zipFile;
	}else if(zipFile instanceof ArrayBuffer){
		zipBuf=zipFile;
	}else {
		zipBuf=await arrayBuffer(zipFile);
	}
	zip=await JSZip$1.loadAsync(zipBuf);

	await parseTgtPath();

	//disk=await JAXDisk.openDisk(diskName,true);
	if(peelRoot){
		let pos;
		willPeel=true;
		//First, find root:
		zip.forEach((path,zipObj)=>{
			if(!willPeel)
				return;
			if(!rootName){
				pos=path.indexOf("/");
				if(pos<0){
					if(zipObj.dir){
						rootName=path+"/";
					}else {
						willPeel=false;
					}
				}else {
					rootName=path.substring(0,pos+1);
				}
			}else {
				if(!path.startsWith(rootName)){
					willPeel=false;
				}
			}
		});
	}
	if(willPeel && rootName){
		let peelLength,stub,date;
		peelLength=rootName.length;
		zip.forEach((path,zipObj)=>{
			if(zipObj.dir){
				if(path!==rootName){
					path=path.substring(peelLength);
					if(path.endsWith("/")){
						path=path.substring(0,path.length-1);
					}
					getDir(path);
				}
			}else {
				path=path.substring(peelLength);
				stub={path:path,zipObj:zipObj};
				fileList.push(stub);
				date=zipObj.date;
				if(date && date.getTime){
					stub.time=date.getTime();
				}
			}
		});
	}else {
		let stub,date;
		zip.forEach((path,zipObj)=>{
			if(zipObj.dir){
				if(path.endsWith("/")){
					path=path.substring(0,path.length-1);
				}
				getDir(path);
			}else {
				stub={path:path,zipObj:zipObj};
				fileList.push(stub);
				date=zipObj.date;
				if(date && date.getTime){
					stub.time=date.getTime();
				}
			}
		});
	}
	
	async function unpackFile(stub){
		let filePath=stub.path;
		let zipObj=stub.zipObj;
		let buf;
		buf=await zipObj.async("uint8array");
		if(tty){
			tty.clearLine();
			tty.textOut("Extracting file: "+filePath);
		}else {
			console.log("Extracting file: "+filePath);
		}
		pms=writeFile(filePath,buf,stub.time||nowTime).then(()=>{
			tty.clearLine();
			tty.textOut("Extracted file: "+filePath);
		});
		pmsList.push(pms);
	}

	for(let i=0,n=fileList.length;i<n;i++){
		await unpackFile(fileList[i]);
	}
	await Promise.all(pmsList);//Wait all file write into disk
	pmsList.splice(0);
	let dirPath,dirEntry;
	dirEntry=dirEntries[""];
	delete dirEntries[""];
	if(zipDir){
		pms=set(zipDir,dirEntry,disk.dbStore);
		pmsList.push(pms);
	}else {
		pms=set(".",dirEntry,disk.dbStore);
		pmsList.push(pms);
	}
	let dirKeys=Object.keys(dirEntries);
	for(let i=0,n=dirKeys.length;i<n;i++){
		dirPath=dirKeys[i];
		dirEntry=dirEntries[dirPath];
		pms=set(dirPrefix+dirPath,dirEntry,disk.dbStore);
		pmsList.push(pms);
	}
	await Promise.all(pmsList);
	if(tty){
		tty.clearLine();
		tty.textOut("Extract zip done");
	}else {
		console.log("Extract zip done");
	}
};

//Auto genterated by Cody
/*}#1GFLV36AE0StartDoc*/
//----------------------------------------------------------------------------
/*#{1GFLV36AF0Constructor+*/
let DataSetup=function(){
/*}#1GFLV36AF0Constructor+*/
	/*#{1GFLV36AF0PreConstruct*/
	/*}#1GFLV36AF0PreConstruct*/
	/*#{1GFLV36AF0Properties+*/
	/*}#1GFLV36AF0Properties+*/
	/*#{1GFLV36AF0PostConstruct*/
	/*}#1GFLV36AF0PostConstruct*/
};
DataSetup.prototype={};
let _DataSetup=DataSetup.prototype;
/*#{1GFLV36AF0ExCodes*/
let dataSetup=_DataSetup;
let downloadDir="/download";

//----------------------------------------------------------------------------
dataSetup.checkOS=async function(logger,checkVersion=true){
	logger.log("Checking installed Tab-OS:");
	if(!await this.checkWorker(logger)){
		logger.log("Service-worker: NA");
		return false;
	}
	logger.log("Service-worker: OK.");
	if(!await this.checkDisks(logger,checkVersion)){
		return false;
	}
	return true;
};

//----------------------------------------------------------------------------
dataSetup.setupOS=async function(logger){
	await this.uninstallWorker(logger);
	await this.installDisks(logger);
	await tabFS.openDisk("doc",1);
	await this.installWorker(logger);
	localStorage.removeItem("LoginVO");
	return true;
};

//----------------------------------------------------------------------------
dataSetup.clearOS=async function(logger){
	await this.dropAllDisks(logger);
	await this.uninstallWorker(logger);
	logger.log("Clear Tab-OS done.");
};

//----------------------------------------------------------------------------
dataSetup.restoreOS=async function(logger,fileBuff){
	//TODO: Code this:
};

//----------------------------------------------------------------------------
//Check service-worker and it's version:
dataSetup.checkWorker=async function(logger){
	let reg,store,scope,version;
	version=appCfg.workerVsnIdx||0;
	scope="/";
	reg=await navigator.serviceWorker.getRegistration(scope);
	if(!reg){
		return false;
	}
	if(version>0){
		store = new DiskStore('JAXSys', "ServiceWorker");
		return get("version", store).then(ver=>{
			return ver>=version;
		});
	}
	return true;
};

//----------------------------------------------------------------------------
dataSetup.checkDisks=async function(logger,checkVersion=true){
	let list,vo;
	list=appCfg.diskInfo;
	for(vo of list){
		if(!checkVersion && vo.name==="coke"){
			if(!await this.checkDiskVersion(vo.name,appCfg.minCokeVsn)){
				logger.log("Disk "+vo.name+": Failed.");
				return false;
			}
		}else {
			if(!await this.checkDiskVersion(vo.name,checkVersion?vo.versionIdx:1)){
				logger.log("Disk "+vo.name+": Failed.");
				return false;
			}
		}
		logger.log("Disk "+vo.name+": OK.");
	}
	return true;
};

//----------------------------------------------------------------------------
dataSetup.installDisks=async function(logger){
	let list,vo,zipURL,zipPath;
	list=appCfg.diskInfo;
	for(vo of list){
		zipPath=vo.zip;
		if(zipPath[0]!=="/"){
			zipURL=pathLib.join(downloadDir,vo.zip);
		}
		await this.installDisk(zipURL,vo.name,logger,true);
	}};

//----------------------------------------------------------------------------
//Install service-worker:
dataSetup.installWorker=async function(logger){
	let reg,store,scope,version;
	//To install，first we install the service-worker:
	logger.state("Installing cokecodes service-worker...");
	logger.log("Start install cokecodes service-worker.");
	scope="/";
	version=appCfg.workerVsnIdx;
	try{
		reg=await navigator.serviceWorker.getRegistration(scope);
		if(reg){
			logger.log("Found existing service-worker, unregister...");
			await reg.unregister();
			logger.log("Existing service-worker, unregister done.");
		}

		logger.log("Registering service-worker...");
		await navigator.serviceWorker.register('../cokeSW.js',{scope:scope,updateViaCache: 'none'});
		console.log("Service-worker registered.");
		if(version>0){
			console.log("Save service-worker version-index: "+version);
			store = new DiskStore('JAXSys', "ServiceWorker");
			await set("version", version, store);
			console.log("Save service-worker version-index done.");
			console.log("Service-worker installation success.");
			return true;
		}
		return true;
	}catch(e){
		logger.log("Install service-worker error: "+e);
		return false;
	}
};

//----------------------------------------------------------------------------
dataSetup.uninstallWorker=async function(logger){
	let scope="/";
	let reg=await navigator.serviceWorker.getRegistration(scope);
	logger.log("Search existing service-worker...");
	if(reg){
		logger.log("Found existing service-worker, unregister...");
		await reg.unregister();
		logger.log("Existing service-worker, unregister done.");
	}
	logger.log("Current service-worker not found.");
	return true;
};

//----------------------------------------------------------------------------
//Check if a disk's version-idx is ok
dataSetup.checkDiskVersion=async function(diskName,checkVersionIdx){
	let text,vo,diskVsnIdx;
	try{
		text=await tabFS.readFile(`/${diskName}/disk.json`,"utf8");
		vo=JSON.parse(text);
		diskVsnIdx=vo.versionIdx||0;
		return diskVsnIdx>=checkVersionIdx;
	}catch(e){
		return false;
	}
	return false;
};

//----------------------------------------------------------------------------
//Extract zip to an empty target path:
dataSetup.extractZipFast=async function(tgtPath,zipFile,logger=null){
	let dirEntries={};
	let pmsList=[];
	let disk,diskName,zipDir,pms,zipDirObj,dirPrefix;

	async function parseTgtPath(){
		if(tgtPath.endsWith("/")){
			tgtPath=tgtPath.substring(tgtPath.length-1);
		}
		if(!tgtPath.startsWith("/")){
			throw Error(`Zip path ${tgtPath} is not full-path`);
		}
		let pos=tgtPath.indexOf("/",1);
		if(pos>0) {
			diskName = tgtPath.substring(1, pos);
			zipDir = tgtPath.substring(pos + 1);
			dirPrefix=zipDir+"/";
		}else {
			diskName = tgtPath.substring(1);
			zipDir = "";
			dirPrefix="";
		}
		disk = await tabFS.openDisk(diskName, true);
		zipDirObj=await get(zipDir||".",disk.dbStore);
		dirEntries[""]=zipDirObj;
	}
	function parsePath(path){
		let pos=path.lastIndexOf("/");
		if(pos>0){
			return [path.substring(0,pos),path.substring(pos+1)];
		}
		return ["",path];
	}
	function getDir(dir){
		let entry;
		entry=dirEntries[dir];
		if(!entry){
			entry={};
			dirEntries[dir]=entry;
			if(dir) {
				let [dirname, basename] = parsePath(dir);
				let upperEntry = getDir(dirname);
				let time = Date.now();
				upperEntry[basename] = { name: basename, dir: 1, createTime: time, modifyTime: time };
			}
		}
		return entry;
	}
	async function digestBytes(buf) {
		let hex;
		const hashBuffer = await crypto.subtle.digest('SHA-256', buf);     // hash the data
		const hashArray = Array.from(new Uint8Array(hashBuffer));          // convert buffer to byte array
		hex= hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
		return hex;
	}
	function writeFile(path,data){
		let [dirname,basename]=parsePath(path);
		let dirEntry=getDir(dirname);
		let time=Date.now();
		return digestBytes(data).then(byteHex=>{
			dirEntry[basename]={name:basename,dir:0,createTime:time,modifyTime:time,size:data.byteLength,modified:true,
								hash:byteHex};
			return set(dirPrefix+path,data,disk.dbStore);
		});
	}

	let zipBuf=await zipFile.arrayBuffer();
	let zip=await JSZip$1.loadAsync(zipBuf);
	let fileList=[];

	await parseTgtPath();

	//disk=await tabFS.openDisk(diskName,true);
	zip.forEach(async (path,zipObj)=>{
		if(zipObj.dir){
			if(path.endsWith("/")){
				path=path.substring(0,path.length-1);
			}
			getDir(path);
		}else {
			fileList.push({path:path,zipObj:zipObj});
		}
	});
	async function unpackFile(stub){
		let filePath=stub.path;
		let zipObj=stub.zipObj;
		let buf;
		buf=await zipObj.async("uint8array");
		if(logger){
			logger.state("Extracting file: "+filePath);
		}else {
			console.log("Extracting file: "+filePath);
		}
		pms=writeFile(filePath,buf).then(()=>{
			if(logger){
				logger.state("Extracted file: "+filePath);
			}else {
				console.log("Extracted file: "+filePath);
			}
		});
		pmsList.push(pms);
	}
	for(let i=0,n=fileList.length;i<n;i++){
		await unpackFile(fileList[i]);
	}
	await Promise.all(pmsList);//Wait all file write into disk
	pmsList.splice(0);
	let dirPath,dirEntry;
	dirEntry=dirEntries[""];
	delete dirEntries[""];
	if(zipDir){
		pms=set(zipDir,dirEntry,disk.dbStore);
		pmsList.push(pms);
	}else {
		pms=set(".",dirEntry,disk.dbStore);
		pmsList.push(pms);
	}
	let dirKeys=Object.keys(dirEntries);
	for(let i=0,n=dirKeys.length;i<n;i++){
		dirPath=dirKeys[i];
		dirEntry=dirEntries[dirPath];
		pms=set(dirPrefix+dirPath,dirEntry,disk.dbStore);
		pmsList.push(pms);
	}
	return Promise.all(pmsList);
};

//------------------------------------------------------------------------
//Download zip from URL, extract to disk by [diskName]
dataSetup.fetchDisk=async function(zipURL,diskName,logger){
	let self=this;
	logger.log("Will fetch file: "+zipURL);
	logger.state("Fetching file: "+zipURL);
	return fetch(zipURL).then(res=>{
		if(res.ok){
			logger.log("dowloading file: "+zipURL);
			return self.extractZipFast("/"+diskName,res,logger);

		}else {
			logger.log("Fetch file "+zipURL+" failed: "+res.status+": "+res.statusText);
			throw "Fecth failed";
		}
	});
};

//------------------------------------------------------------------------
//Install a disk from zipURL.
dataSetup.installDisk=async function(zipURL,diskName,logger,deleteOld=1){
	let disk;
	//Open current disk:
	disk=await tabFS.openDisk(diskName,0);
	if(disk && deleteOld){
		//Delete current disk:
		await tabFS.dropDisk(diskName);
	}
	disk=await tabFS.openDisk(diskName,1);
	await tabFS.setDiskAttr(diskName,"diskType","System");
	return this.fetchDisk(zipURL,diskName,logger);
};

//------------------------------------------------------------------------
//Drop all disk in sandbox
dataSetup.dropAllDisks=async function(logger){
	let diskNames,diskName;
	diskNames=await tabFS.getDiskNames();
	if(diskNames){
		for(diskName of diskNames){
			logger.log(`Drop disk: ${diskName}`);
			await tabFS.dropDisk(diskName,false);
		}
	}
};

//----------------------------------------------------------------------------
dataSetup.checkoutDisk=async function(cloudDiskName,versionIdx,diskName){
	//TODO: Code this:
};
/*Cody Project Doc*/
//{
//	"type": "docfile",
//	"def": "DataDoc",
//	"jaxId": "1GFLV36AE0",
//	"attrs": {
//		"editObjs": {
//			"jaxId": "1GFLV36AE1",
//			"attrs": {
//				"DataSetup": {
//					"type": "objclass",
//					"def": "ObjClass",
//					"jaxId": "1GFLV36AF0",
//					"attrs": {
//						"constructArgs": {
//							"jaxId": "1GFLV36AF1",
//							"attrs": {}
//						},
//						"superClass": "",
//						"properties": {
//							"jaxId": "1GFLV36AF2",
//							"attrs": {}
//						},
//						"functions": {
//							"jaxId": "1GFLV36AF3",
//							"attrs": {}
//						},
//						"mockupOnly": "false",
//						"nullMockup": "false"
//					},
//					"mockups": {}
//				}
//			}
//		}
//	}
//}

//----------------------------------------------------------------------------
const regSearchEscEnd=/[A-Za-z]/g;
function index2Color(c){
	let r,g,b;
	switch(c)
	{
		case 0:
			return "rgba(0,0,0,1)";
		case 1:
			return "rgba(128,0,0,1)";
		case 2:
			return "rgba(0,128,0,1)";
		case 3:
			return "rgba(128,128,0,1)";
		case 4:
			return "rgba(0,0,128,1)";
		case 5:
			return "rgba(128,0,128,1)";
		case 6:
			return "rgba(0,128,128,1)";
		case 7:
			return "rgba(192,192,192,1)";
		//Bright:
		case 8:
			return "rgba(128,128,128,1)";
		case 9:
			return "rgba(255,0,0,1)";
		case 10:
			return "rgba(0,255,0,1)";
		case 11:
			return "rgba(255,255,0,1)";
		case 12:
			return "rgba(0,0,255,1)";
		case 13:
			return "rgba(255,0,255,1)";
		case 14:
			return "rgba(0,255,255,1)";
		case 15:
			return "rgba(255,255,255,1)";
	}
	if(c>=232 && c<=255){
		c-=231;
		c=c*10;
		return `rgba(${c},${c},${c},1)`;
	}else if(c<232){
		c-=16;
		b=c%6;
		c=Math.floor(c/6);
		g=c%6;
		c=Math.floor(c/6);
		r=c%6;
		return `rgba(${r},${g},${b},1)`;
	}
	return "rgba(0,0,0,1)";
}

//****************************************************************************
//TTY:
//****************************************************************************
class CokeTTY extends EventEmitter$1
{
	constructor (div,host,inputHeader="coke"){
		super();
		this.div=div;
		this.host=host;
		
		this.lines=[];
		this.divInput=null;
		this.lastLine=null;
		this.inputHeader=inputHeader;
		this.inputPrefix="$>";
		this.segChNum=8;
		this.lineSeq=0;
		this.isInputPassword=false;
		
		this.divInput=null;
		if(div) {
			div.style.overflowY = "scroll";
			div.style.overflowX = "scroll";
		}
		
		this.cursorLine=null;		//Cursor line:
		this.cursorX=0;				//Cursor column:
		
		if(div) {
			this._outLine("");
		}
		this.defColorTxt=this.colorTxt="rgba(0,0,0,1)";
		this.defColorBG=this.colorBG="rgba(255,255,255,0)";
		this.defFontWeight="";
		this.fontWeight="";
	}
	
	//-----------------------------------------------------------------------
	newTextSpan(){
		let span,style;
		span=document.createElement('span');
		style = span.style;
		style.width = "auto";
		style.height = "";
		style.wordBreak = "break-word";
		style.whiteSpace = "pre";
		style.textOverflow = "";
		style.alignSelf = "";
		style.textAlign = "";
		style.fontFamily = "monospace";
		style.fontSize = "12px";
		style.color = this.colorTxt;
		style.fontWeight=this.fontWeight;
		return span;
	}
	
	//-----------------------------------------------------------------------
	parseEscText(text){
		let pts,n;
		pts=text.split(";");
		n=parseInt(pts[0]);
		while(n===0 || n===1){
			pts.shift();
			if(n===0){
				this.colorTxt=this.defColorTxt;
				this.colorBG=this.defColorBG;
				this.fontWeight="";
			}else {
				this.fontWeight="bold";
			}
			if(pts.length) {
				n = parseInt(pts[0]);
			}else {
				this.colorTxt=this.defColorTxt;
				this.colorBG=this.defColorBG;
				return;
			}
		}
		
		if(n===0){//Reset text:
			this.colorTxt=this.defColorTxt;
			this.colorBG=this.defColorBG;
		}else if(n>=30 && n<=37){//Set foreground color
			switch(n){
				case 30://Black
					this.colorTxt="rgba(0,0,0,1)";
					break;
				case 31://Red
					this.colorTxt="rgba(222,56,43,1)";
					break;
				case 32://Green
					this.colorTxt="rgba(57,181,74,1)";
					break;
				case 33://Yellow
					this.colorTxt="rgba(255,199,6,1)";
					break;
				case 34://Blue
					this.colorTxt="rgba(0,111,184,1)";
					break;
				case 35://Magenta
					this.colorTxt="rgba(118,38,113,1)";
					break;
				case 36://Cyan
					this.colorTxt="rgba(44,181,233,1)";
					break;
				case 37://White
					this.colorTxt="rgba(229,229,229,1)";
					break;
			}
		}else if(n===38){//Set foreground color
			let c;
			n=pts[1];
			if(n===5){//256 colors
				c=parseInt(pts[2]);
				this.colorTxt=index2Color(c);
			}else if(n===2){//RGB colors
				this.colorTxt=`rgba(${pts[2]},${pts[3]},${pts[4]},1)`;
			}
		}else if(n===39){
			this.colorTxt=this.defColorTxt;
		}else if(n>=40 && n<=47){//Set background color
			switch(n){
				case 40://Black
					this.colorBG="rgba(1,1,1,1)";
					break;
				case 41://Red
					this.colorBG="rgba(222,56,43,1)";
					break;
				case 42://Green
					this.colorBG="rgba(57,181,74,1)";
					break;
				case 43://Yellow
					this.colorBG="rgba(255,199,6,1)";
					break;
				case 44://Blue
					this.colorBG="rgba(0,111,184,1)";
					break;
				case 45://Magenta
					this.colorBG="rgba(118,38,113,1)";
					break;
				case 46://Cyan
					this.colorBG="rgba(44,181,233,1)";
					break;
				case 47://White
					this.colorBG="rgba(229,229,229,1)";
					break;
			}
		}else if(n===48){//Set background color
			let c;
			n=pts[1];
			if(n===5){//256 colors
				c=parseInt(pts[2]);
				this.colorBG=index2Color(c);
			}else if(n===2){//RGB colors
				this.colorBG=`rgba(${pts[2]},${pts[3]},${pts[4]},1)`;
			}
		}else if(n===49){
			this.colorBG=this.defColorBG;
		}else if(n>=90 && n<=97){//Set light foreground color
			switch(n){
				case 90://Black
					this.colorTxt="rgba(128,128,128,1)";
					break;
				case 91://Red
					this.colorTxt="rgba(255,0,0,1)";
					break;
				case 92://Green
					this.colorTxt="rgba(0,255,0,1)";
					break;
				case 93://Yellow
					this.colorTxt="rgba(255,255,0,1)";
					break;
				case 94://Blue
					this.colorTxt="rgba(0,0,255,1)";
					break;
				case 95://Magenta
					this.colorTxt="rgba(255,0,255,1)";
					break;
				case 96://Cyan
					this.colorTxt="rgba(0,255,255,1)";
					break;
				case 97://White
					this.colorTxt="rgba(255,255,255,1)";
					break;
			}
		}else if(n>=100 && n<=107){//Set light background color
			switch(n){
				case 100://Black
					this.colorBG="rgba(128,128,128,1)";
					break;
				case 101://Red
					this.colorBG="rgba(255,0,0,1)";
					break;
				case 102://Green
					this.colorBG="rgba(0,255,0,1)";
					break;
				case 103://Yellow
					this.colorBG="rgba(255,255,0,1)";
					break;
				case 104://Blue
					this.colorBG="rgba(0,0,255,1)";
					break;
				case 105://Magenta
					this.colorBG="rgba(255,0,255,1)";
					break;
				case 106://Cyan
					this.colorBG="rgba(0,255,255,1)";
					break;
				case 107://White
					this.colorBG="rgba(255,255,255,1)";
					break;
			}
		}
	}
	
	//-----------------------------------------------------------------------
	//Output a seg of text, no new line, support \t .
	_outLnText(text,line=null,pos=0){
		let idx,lines,curText,outText,lineText,segText;
		let pts,segChNum,span;
		
		function renderTab(){
			let n,m,i;
			n=lineText.length+curText.length;
			m=Math.floor(n/segChNum)*segChNum+segChNum;
			n=m-n;
			for(i=0;i<n;i++){
				curText+=" ";
			}
		}
		if(!line) {
			lines = this.lines;
			idx = lines.length - 1;
			line = lines[idx];
		}
		lineText=line.innerText;
		curText="";//line.innerText;
		segChNum=this.segChNum;
		pts=text.split("\t");
		pts.forEach((sub,idx)=>{
			if(idx!==0){
				renderTab();
			}
			curText+=sub;
		});
		if(pos===lineText.length){
			let escPos,escChar;
			outText="";
			span = line.curSpan;
			if (!span) {
				line.curSpan = span = this.newTextSpan();
				line.appendChild(span);
			}
			escPos=curText.indexOf('\x1b');
			if(escPos>=0){
				//Complex way:
				do{
					segText=curText.substring(0,escPos);
					line.curSpan.innerText+=segText;
					outText+=segText;
					curText=curText.substring(escPos+1);
					escChar=curText[0];
					if(escChar==="["){
						let mkPos=curText.search(regSearchEscEnd);
						let mk=curText[mkPos];
						if(mk==="m"){//Color:
							let colorText=curText.substring(1,mkPos);
							curText=curText.substring(mkPos+1);
							if(colorText==="0"){
								this.colorTxt=this.defColorTxt;
								this.colorBG=this.defColorBG;
								this.fontWeight="";
							}else {
								this.parseEscText(colorText);
							}
							let newSpan=this.newTextSpan();
							line.appendChild(newSpan);
							line.curSpan=newSpan;
							console.log("Terminal set color: "+colorText);
						}else {
							//ignore
							curText=curText.substring(mkPos+1);
						}
					}else {
						line.curSpan.innerText+=curText;
						outText+=curText;
						curText="";
					}
					escPos=curText.indexOf('\x1b');
				}while(escPos>0);
				line.curSpan.innerText+=curText;
				outText+=curText;
			}else {
				line.curSpan.innerText = line.curSpan.innerText+curText;
				outText=curText;
			}
		}else {			
			lineText = lineText.substring(0, pos) + curText + lineText.substring(pos + curText.length);
			line.innerText = lineText;
			line.curSpan=null;
			outText=curText;
		}
		//Record cursor pos:
		this.cursorX=pos+outText.length;
		this.cursorLine=line;
	}
	
	//-----------------------------------------------------------------------
	//Output a line:
	_outLine(text,curLine=null){
		let div,style,divLines,lines;
		divLines=this.div;
		lines=this.lines;
		if(curLine){
			div=curLine.nextSibling;
		}else {
			curLine=this.cursorLine||this.lastLine;
			if(curLine){
				div=curLine.nextSibling;
				if(div===this.divInput){
					div=null;
				}
			}
		}
		if(!div && divLines) {
			div = document.createElement('div');
			style = div.style;
			style.width = "auto";
			style.height = "";
			style.wordBreak = "break-word";
			style.whiteSpace = "pre";
			style.textOverflow = "";
			style.alignSelf = "";
			style.textAlign = "";
			style.fontFamily = "monospace";
			style.fontSize = "12px";
			style.color = "rgba(0,0,0,1)";
			style.paddingLeft="5px";
			div.spellcheck = false;
			if(this.divInput){
				divLines.insertBefore(div,this.divInput);
			}else {
				divLines.appendChild(div);
			}
			lines.push(div);
			div.lineSeq = this.lineSeq++;
			this.lastLine = div;
			if (lines.length > 200) {
				divLines.removeChild(lines[0]);
				lines.shift();
			}
		}
		this.cursorLine=div;
		this.cursorX=0;
		this._outLnText(text,div,0);
		return div;
	}
	
	//-----------------------------------------------------------------------
	//Output [text], if [scroll] is true, scorll view to bottom.
	textOut(text,scroll=1){
		let pts,lead,i,n;
		if(typeof(text)!=="string"){
			text=""+text;
		}
		//console.log(text);
		if(this.div) {
			pts = text.split("\n");
			lead = pts[0];
			if (lead) {
				if(!this.cursorLine && this.divInput){
					this._outLine(lead);
				}else {
					this._outLnText(lead, this.cursorLine, this.cursorX);
				}
			}
			n = pts.length;
			if (n > 1) {
				for (i = 1; i < n; i++) {
					this._outLine(pts[i]);
				}
			}
			if (scroll) {
				//滚动element:
				this.div.scrollTop = this.div.scrollHeight;
			}
		}
		if(this.host){
			this.host.sendRemoteMsg({
				msg:"tty",
				func:"textOut",
				args:[text,scroll]
			});
		}
	}
	
	//-----------------------------------------------------------------------
	//Output a seg of HTML elemts:
	htmlOut(htmlText,scroll=1){
		let divLines,div,style;
		divLines=this.div;
		if(divLines) {
			div = document.createElement('div');
			style = div.style;
			style.width = "auto";
			style.height = "";
			style.color = "rgba(0,0,0,1)";
			style.paddingLeft="10px";
			div.spellcheck = false;
			divLines.appendChild(div);
			this.lines.push(div);
			div.lineSeq = this.lineSeq++;
			div.innerHTML=htmlText;
			this.lastLine = div;
			if (this.lines.length > 200) {
				divLines.removeChild(this.lines[0]);
				this.lines.shift();
			}
			this._outLine("",scroll);
		}else if(this.host){
			this.host.sendRemoteMsg({
				msg:"tty",
				func:"htmlOut",
				args:[htmlText,scroll]
			});
		}
	}
	
	//-----------------------------------------------------------------------
	//Start text input :
	startInput(prefix=null,password=false,initText=""){
		let div,path;
		let passwordText="";
		
		path=JAXDisk.appPath;
		if(this.div) {
			if(prefix!==null){
				this.inputPrefix=prefix;
			}else {
				this.inputPrefix=""+this.inputHeader+" "+path+" $> ";
			}
			div = this.divInput;
			if (!div) {
				this._outLine("");
				div = this.lastLine;
				if (!div || div.innerText) {
					div = this._outLine(this.inputPrefix+initText, this.lastLine);
				} else {
					div.innerText = this.inputPrefix+initText;
					div.curSpan=null;
				}
				this.divInput = div;
				this.cursorLine =null;this.cursorX=0;
				div.curInputText = div.inputPrefix = this.inputPrefix;
				div.contentEditable = true;
				div.style.outlineStyle = "none";
				div.style.backgroundColor = "rgba(230,240,255,1)";
				div.isPassword=!!password;
				if(password){
					div.addEventListener("keydown", evt=>{
						switch(evt.key){
							case "Enter":
								evt.preventDefault();
								evt.stopPropagation();
								this.endInput(passwordText);
								break;
							case "Backspace":
								passwordText=passwordText.substring(0,passwordText.length-1);
								evt.preventDefault();
								evt.stopPropagation();
								break;
						}
					}, true);
				}else {
					div.addEventListener("keydown", this.OnKeyDown.bind(this), true);
				}
				div.oninput = () => {
					let text;
					text = div.innerText;
					if(password){
						if (!text.startsWith(div.inputPrefix)) ; else {
							text=text.substring(div.inputPrefix.length);
							passwordText+=text;
						}
						div.innerText = div.inputPrefix;
						div.curSpan=null;
						window.getSelection().collapse(div.firstChild, div.inputPrefix.length);
					}else {
						if (!text.startsWith(div.inputPrefix)) {
							div.innerText = div.inputPrefix;
							div.curSpan=null;
							window.getSelection().collapse(div.firstChild, div.inputPrefix.length);
						}
					}
				};
				window.getSelection().collapse(div.firstChild, div.innerText.length);
			}
			this.div.scrollTop = this.div.scrollHeight;
			div.focus();
			window.setTimeout(() => {
				div.focus();
				div.selectionStart = div.selectionEnd = this.inputPrefix.length;
			}, 0);
		}else if(this.host){
			this.host.sendRemoteMsg({
				msg:"StartInput",
				prefix:prefix,
				initText:initText,
				password:password
			});
		}
		this.isInputPassword=password;
	}
	
	//-----------------------------------------------------------------------
	//End text input:
	endInput(text){
		let div;
		if(this.div) {
			div=this.divInput;
			if(div) {
				div.contentEditable = false;
				div.style.backgroundColor = "rgba(0,0,0,0)";
				this.divInput = null;
			}
			this._outLine("", this.lastLine);
		}
		if(!this.emit("LineInput",text)) {
			this.stdin.push(text + "\n");
		}
	}
	
	//-----------------------------------------------------------------------
	//Set the "input" text
	setInputText(text){
		let div;
		div=this.divInput;
		if(!div){
			return;
		}
		if(div.inputPrefix){
			text=div.inputPrefix+text;
		}
		div.innerText=text;
		div.curSpan=null;
		window.getSelection().collapse(div.firstChild,text.length);
	}
	
	//-----------------------------------------------------------------------
	//Get current "input" text:
	getInputText(){
		let text,div;
		div=this.divInput;
		if(!div){
			return null;
		}
		text= div.innerText;
		if(div.inputPrefix && text.startsWith(div.inputPrefix)){
			text=text.substring(div.inputPrefix.length);
		}
		return text;
	}
	
	//-----------------------------------------------------------------------
	//Handle key events:
	OnKeyDown(e){
		let div;
		div=this.divInput;
		this.emit("KeyDown",e);
		//console.log(e);
		switch(e.key)
		{
			case "c":{
				if(e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey){
					this.emit("KeyInExec","BreakCmd");
				}
				break;
			}
			case "Enter":{
				let cmd;
				if(div){
					//TODO: When Shift down, don't send message:
					let text;
					cmd=div.innerText;
					if(div.inputPrefix && cmd.startsWith(div.inputPrefix)){
						cmd=cmd.substring(div.inputPrefix.length);
					}
					text=this.getInputText();
					this.endInput(text);
					e.preventDefault();
					e.stopPropagation();
					return;
				}
				break;
			}
			case "ArrowDown":
			case "ArrowUp":
			case "Tab":{
				if(div){
					this.emit("ToolKey",e.key);
					e.preventDefault();
					e.stopPropagation();
					return;
				}
				break;
			}
		}
	}
	
	//-----------------------------------------------------------------------
	//Clear screen
	clear(){
		if(this.div) {
			let restartInput=false,inputPrefix,inputText,isPswd;
			if(this.divInput){
				restartInput=true;
				inputPrefix=this.inputPrefix;
				inputText=this.getInputText();
				isPswd=this.divInput.isPassword;
			}
			this.div.innerHTML = "";
			this.lines.splice(0);
			this.lastLine = null;
			this.divInput = null;
			this._outLine("");
			if(restartInput){
				this.startInput(inputPrefix,isPswd,inputText);
			}
		}else if(this.host){
			this.host.sendRemoteMsg({
				msg:"tty",
				func:"clear",
				args:[]
			});
		}
	}
	
	//-----------------------------------------------------------------------
	//Clear a line by dir
	clearLine(dir){
		let line,curText;
		if(this.div) {
			line = this.cursorLine;
			if (!line) {
				return;
			}
			switch (dir) {
				case -1:
					curText = line.innerText;
					curText = curText.substring(this.cursorX);
					line.innerText = curText;
					line.curSpan=null;
					this.cursorX = 0;
					break;
				case 1:
					curText = line.innerText;
					curText = curText.substring(0, this.cursorX);
					line.innerText = curText;
					line.curSpan=null;
					break;
				default:
				case 0:
					line.innerText = "";
					line.curSpan=null;
					break;
			}
		}else if(this.host){
			this.host.sendRemoteMsg({
				msg:"tty",
				func:"clearLine",
				args:[dir]
			});
		}
	}
	
	//-----------------------------------------------------------------------
	//Clear all text below cursor
	clearScreenDown(){
		let line,lines,idx,i,n,divLines;
		if(this.div) {
			line = this.cursorLine;
			lines = this.lines;
			divLines = this.div;
			if (!line) {
				this.clear();
				return;
			}
			idx = lines.indexOf(line);
			if (idx >= 0) {
				n = lines.length;
				for (i = idx + 1; i < n; i++) {
					divLines.removeChild(lines[i]);
				}
				lines.splice(idx + 1);
			}
			this.clearLine(1);
		}else if(this.host);
	}
	
	//-----------------------------------------------------------------------
	//Set cursor pos
	setCursorPos(x,y){
		let line;
		if(this.div) {
			if (y >= 0) {
				let lines;
				lines = this.lines;
				line = lines[y] || this.lastLine;
			} else {
				line = this.cursorLine;
			}
			this.cursorLine = line;
			x = x < 0 ? 0 : x;
			x = x > line.innerText.length ? line.innerText.length : x;
			this.cursorX = x;
		}else if(this.host);
	}
	
	//-----------------------------------------------------------------------
	//Move cursor pos by delta size:
	moveCursor(dx,dy){
		let x,y;
		if(this.div) {
			if (this.cursorLine) {
				y = this.lines.indexOf(this.cursorLine);
				y += dy;
			}
			x = this.cursorX + dx;
			setCursorPos(x, y);
		}else if(this.host);
	}
	
	//-----------------------------------------------------------------------
	//Helper function to read quession answer from tty.
	readLine(caption,text=""){
		return new Promise((doneFunc,errFunc)=>{
			this.once("LineInput",(text)=>{
				doneFunc(text);
			});
			this.startInput(caption,0,text);
		})
	}
	
	//-----------------------------------------------------------------------
	//Helper function to read password from tty:
	readPassword(caption){
		return new Promise((doneFunc,errFunc)=>{
			this.once("LineInput",(text)=>{
				doneFunc(text);
			});
			this.startInput(caption,true);
		})
	}
	
	//-----------------------------------------------------------------------
	//get tab char-size:
	getTabSize(size){
		return this.segChNum;
	}

	//-----------------------------------------------------------------------
	//set tab char-size:
	setTabSize(size){
		this.segChNum=size;
		if(!this.div){
			this.host.sendHostMsg({
				msg:"tty",
				func:"setTabSize",
				args:[size]
			});
		}
	}
	
	//-----------------------------------------------------------------------
	//logger API:
	log(text,scroll=1){
		if(this.isLastTextState){
			this.textOut("\n",scroll);
		}
		this.isLastTextState=false;
		this.textOut(text+"\n",scroll);
	}
	state(text){
		this.clearLine();
		this.textOut(text,true);
		this.isLastTextState=1;
	}
}
let LitTTY=CokeTTY;

/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */
function t(t){let e=t.length;for(;--e>=0;)t[e]=0;}const e=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),a=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),i=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),n=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),s=new Array(576);t(s);const r=new Array(60);t(r);const l=new Array(512);t(l);const o=new Array(256);t(o);const h=new Array(29);t(h);const d=new Array(30);function _(t,e,a,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=a,this.elems=i,this.max_length=n,this.has_stree=t&&t.length;}let f,c,u;function w(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e;}t(d);const m=t=>t<256?l[t]:l[256+(t>>>7)],b=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255;},g=(t,e,a)=>{t.bi_valid>16-a?(t.bi_buf|=e<<t.bi_valid&65535,b(t,t.bi_buf),t.bi_buf=e>>16-t.bi_valid,t.bi_valid+=a-16):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=a);},p=(t,e,a)=>{g(t,a[2*e],a[2*e+1]);},k=(t,e)=>{let a=0;do{a|=1&t,t>>>=1,a<<=1;}while(--e>0);return a>>>1},v=(t,e,a)=>{const i=new Array(16);let n,s,r=0;for(n=1;n<=15;n++)r=r+a[n-1]<<1,i[n]=r;for(s=0;s<=e;s++){let e=t[2*s+1];0!==e&&(t[2*s]=k(i[e]++,e));}},y=t=>{let e;for(e=0;e<286;e++)t.dyn_ltree[2*e]=0;for(e=0;e<30;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.sym_next=t.matches=0;},x=t=>{t.bi_valid>8?b(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0;},z=(t,e,a,i)=>{const n=2*e,s=2*a;return t[n]<t[s]||t[n]===t[s]&&i[e]<=i[a]},A=(t,e,a)=>{const i=t.heap[a];let n=a<<1;for(;n<=t.heap_len&&(n<t.heap_len&&z(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!z(e,i,t.heap[n],t.depth));)t.heap[a]=t.heap[n],a=n,n<<=1;t.heap[a]=i;},E=(t,i,n)=>{let s,r,l,_,f=0;if(0!==t.sym_next)do{s=255&t.pending_buf[t.sym_buf+f++],s+=(255&t.pending_buf[t.sym_buf+f++])<<8,r=t.pending_buf[t.sym_buf+f++],0===s?p(t,r,i):(l=o[r],p(t,l+256+1,i),_=e[l],0!==_&&(r-=h[l],g(t,r,_)),s--,l=m(s),p(t,l,n),_=a[l],0!==_&&(s-=d[l],g(t,s,_)));}while(f<t.sym_next);p(t,256,i);},R=(t,e)=>{const a=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,s=e.stat_desc.elems;let r,l,o,h=-1;for(t.heap_len=0,t.heap_max=573,r=0;r<s;r++)0!==a[2*r]?(t.heap[++t.heap_len]=h=r,t.depth[r]=0):a[2*r+1]=0;for(;t.heap_len<2;)o=t.heap[++t.heap_len]=h<2?++h:0,a[2*o]=1,t.depth[o]=0,t.opt_len--,n&&(t.static_len-=i[2*o+1]);for(e.max_code=h,r=t.heap_len>>1;r>=1;r--)A(t,a,r);o=s;do{r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],A(t,a,1),l=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=l,a[2*o]=a[2*r]+a[2*l],t.depth[o]=(t.depth[r]>=t.depth[l]?t.depth[r]:t.depth[l])+1,a[2*r+1]=a[2*l+1]=o,t.heap[1]=o++,A(t,a,1);}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const a=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,s=e.stat_desc.has_stree,r=e.stat_desc.extra_bits,l=e.stat_desc.extra_base,o=e.stat_desc.max_length;let h,d,_,f,c,u,w=0;for(f=0;f<=15;f++)t.bl_count[f]=0;for(a[2*t.heap[t.heap_max]+1]=0,h=t.heap_max+1;h<573;h++)d=t.heap[h],f=a[2*a[2*d+1]+1]+1,f>o&&(f=o,w++),a[2*d+1]=f,d>i||(t.bl_count[f]++,c=0,d>=l&&(c=r[d-l]),u=a[2*d],t.opt_len+=u*(f+c),s&&(t.static_len+=u*(n[2*d+1]+c)));if(0!==w){do{for(f=o-1;0===t.bl_count[f];)f--;t.bl_count[f]--,t.bl_count[f+1]+=2,t.bl_count[o]--,w-=2;}while(w>0);for(f=o;0!==f;f--)for(d=t.bl_count[f];0!==d;)_=t.heap[--h],_>i||(a[2*_+1]!==f&&(t.opt_len+=(f-a[2*_+1])*a[2*_],a[2*_+1]=f),d--);}})(t,e),v(a,h,t.bl_count);},Z=(t,e,a)=>{let i,n,s=-1,r=e[1],l=0,o=7,h=4;for(0===r&&(o=138,h=3),e[2*(a+1)+1]=65535,i=0;i<=a;i++)n=r,r=e[2*(i+1)+1],++l<o&&n===r||(l<h?t.bl_tree[2*n]+=l:0!==n?(n!==s&&t.bl_tree[2*n]++,t.bl_tree[32]++):l<=10?t.bl_tree[34]++:t.bl_tree[36]++,l=0,s=n,0===r?(o=138,h=3):n===r?(o=6,h=3):(o=7,h=4));},U=(t,e,a)=>{let i,n,s=-1,r=e[1],l=0,o=7,h=4;for(0===r&&(o=138,h=3),i=0;i<=a;i++)if(n=r,r=e[2*(i+1)+1],!(++l<o&&n===r)){if(l<h)do{p(t,n,t.bl_tree);}while(0!=--l);else 0!==n?(n!==s&&(p(t,n,t.bl_tree),l--),p(t,16,t.bl_tree),g(t,l-3,2)):l<=10?(p(t,17,t.bl_tree),g(t,l-3,3)):(p(t,18,t.bl_tree),g(t,l-11,7));l=0,s=n,0===r?(o=138,h=3):n===r?(o=6,h=3):(o=7,h=4);}};let S=!1;const D=(t,e,a,i)=>{g(t,0+(i?1:0),3),x(t),b(t,a),b(t,~a),a&&t.pending_buf.set(t.window.subarray(e,e+a),t.pending),t.pending+=a;};var T=(t,e,a,i)=>{let l,o,h=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,a=4093624447;for(e=0;e<=31;e++,a>>>=1)if(1&a&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<256;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0})(t)),R(t,t.l_desc),R(t,t.d_desc),h=(t=>{let e;for(Z(t,t.dyn_ltree,t.l_desc.max_code),Z(t,t.dyn_dtree,t.d_desc.max_code),R(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*n[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),l=t.opt_len+3+7>>>3,o=t.static_len+3+7>>>3,o<=l&&(l=o)):l=o=a+5,a+4<=l&&-1!==e?D(t,e,a,i):4===t.strategy||o===l?(g(t,2+(i?1:0),3),E(t,s,r)):(g(t,4+(i?1:0),3),((t,e,a,i)=>{let s;for(g(t,e-257,5),g(t,a-1,5),g(t,i-4,4),s=0;s<i;s++)g(t,t.bl_tree[2*n[s]+1],3);U(t,t.dyn_ltree,e-1),U(t,t.dyn_dtree,a-1);})(t,t.l_desc.max_code+1,t.d_desc.max_code+1,h+1),E(t,t.dyn_ltree,t.dyn_dtree)),y(t),i&&x(t);},O={_tr_init:t=>{S||((()=>{let t,n,w,m,b;const g=new Array(16);for(w=0,m=0;m<28;m++)for(h[m]=w,t=0;t<1<<e[m];t++)o[w++]=m;for(o[w-1]=m,b=0,m=0;m<16;m++)for(d[m]=b,t=0;t<1<<a[m];t++)l[b++]=m;for(b>>=7;m<30;m++)for(d[m]=b<<7,t=0;t<1<<a[m]-7;t++)l[256+b++]=m;for(n=0;n<=15;n++)g[n]=0;for(t=0;t<=143;)s[2*t+1]=8,t++,g[8]++;for(;t<=255;)s[2*t+1]=9,t++,g[9]++;for(;t<=279;)s[2*t+1]=7,t++,g[7]++;for(;t<=287;)s[2*t+1]=8,t++,g[8]++;for(v(s,287,g),t=0;t<30;t++)r[2*t+1]=5,r[2*t]=k(t,5);f=new _(s,e,257,286,15),c=new _(r,a,0,30,15),u=new _(new Array(0),i,0,19,7);})(),S=!0),t.l_desc=new w(t.dyn_ltree,f),t.d_desc=new w(t.dyn_dtree,c),t.bl_desc=new w(t.bl_tree,u),t.bi_buf=0,t.bi_valid=0,y(t);},_tr_stored_block:D,_tr_flush_block:T,_tr_tally:(t,e,a)=>(t.pending_buf[t.sym_buf+t.sym_next++]=e,t.pending_buf[t.sym_buf+t.sym_next++]=e>>8,t.pending_buf[t.sym_buf+t.sym_next++]=a,0===e?t.dyn_ltree[2*a]++:(t.matches++,e--,t.dyn_ltree[2*(o[a]+256+1)]++,t.dyn_dtree[2*m(e)]++),t.sym_next===t.sym_end),_tr_align:t=>{g(t,2,3),p(t,256,s),(t=>{16===t.bi_valid?(b(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8);})(t);}};var I=(t,e,a,i)=>{let n=65535&t|0,s=t>>>16&65535|0,r=0;for(;0!==a;){r=a>2e3?2e3:a,a-=r;do{n=n+e[i++]|0,s=s+n|0;}while(--r);n%=65521,s%=65521;}return n|s<<16|0};const F=new Uint32Array((()=>{let t,e=[];for(var a=0;a<256;a++){t=a;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[a]=t;}return e})());var L=(t,e,a,i)=>{const n=F,s=i+a;t^=-1;for(let a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return -1^t},N={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},B={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:C,_tr_stored_block:H,_tr_flush_block:M,_tr_tally:j,_tr_align:K}=O,{Z_NO_FLUSH:P,Z_PARTIAL_FLUSH:Y,Z_FULL_FLUSH:G,Z_FINISH:X,Z_BLOCK:W,Z_OK:q,Z_STREAM_END:J,Z_STREAM_ERROR:Q,Z_DATA_ERROR:V,Z_BUF_ERROR:$,Z_DEFAULT_COMPRESSION:tt,Z_FILTERED:et,Z_HUFFMAN_ONLY:at,Z_RLE:it,Z_FIXED:nt,Z_DEFAULT_STRATEGY:st,Z_UNKNOWN:rt,Z_DEFLATED:lt}=B,ot=(t,e)=>(t.msg=N[e],e),ht=t=>2*t-(t>4?9:0),dt=t=>{let e=t.length;for(;--e>=0;)t[e]=0;},_t=t=>{let e,a,i,n=t.w_size;e=t.hash_size,i=e;do{a=t.head[--i],t.head[i]=a>=n?a-n:0;}while(--e);e=n,i=e;do{a=t.prev[--i],t.prev[i]=a>=n?a-n:0;}while(--e)};let ft=(t,e,a)=>(e<<t.hash_shift^a)&t.hash_mask;const ct=t=>{const e=t.state;let a=e.pending;a>t.avail_out&&(a=t.avail_out),0!==a&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+a),t.next_out),t.next_out+=a,e.pending_out+=a,t.total_out+=a,t.avail_out-=a,e.pending-=a,0===e.pending&&(e.pending_out=0));},ut=(t,e)=>{M(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,ct(t.strm);},wt=(t,e)=>{t.pending_buf[t.pending++]=e;},mt=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e;},bt=(t,e,a,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),a),1===t.state.wrap?t.adler=I(t.adler,e,n,a):2===t.state.wrap&&(t.adler=L(t.adler,e,n,a)),t.next_in+=n,t.total_in+=n,n)},gt=(t,e)=>{let a,i,n=t.max_chain_length,s=t.strstart,r=t.prev_length,l=t.nice_match;const o=t.strstart>t.w_size-262?t.strstart-(t.w_size-262):0,h=t.window,d=t.w_mask,_=t.prev,f=t.strstart+258;let c=h[s+r-1],u=h[s+r];t.prev_length>=t.good_match&&(n>>=2),l>t.lookahead&&(l=t.lookahead);do{if(a=e,h[a+r]===u&&h[a+r-1]===c&&h[a]===h[s]&&h[++a]===h[s+1]){s+=2,a++;do{}while(h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&s<f);if(i=258-(f-s),s=f-258,i>r){if(t.match_start=e,r=i,i>=l)break;c=h[s+r-1],u=h[s+r];}}}while((e=_[e&d])>o&&0!=--n);return r<=t.lookahead?r:t.lookahead},pt=t=>{const e=t.w_size;let a,i,n;do{if(i=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-262)&&(t.window.set(t.window.subarray(e,e+e-i),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,t.insert>t.strstart&&(t.insert=t.strstart),_t(t),i+=e),0===t.strm.avail_in)break;if(a=bt(t.strm,t.window,t.strstart+t.lookahead,i),t.lookahead+=a,t.lookahead+t.insert>=3)for(n=t.strstart-t.insert,t.ins_h=t.window[n],t.ins_h=ft(t,t.ins_h,t.window[n+1]);t.insert&&(t.ins_h=ft(t,t.ins_h,t.window[n+3-1]),t.prev[n&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=n,n++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead<262&&0!==t.strm.avail_in)},kt=(t,e)=>{let a,i,n,s=t.pending_buf_size-5>t.w_size?t.w_size:t.pending_buf_size-5,r=0,l=t.strm.avail_in;do{if(a=65535,n=t.bi_valid+42>>3,t.strm.avail_out<n)break;if(n=t.strm.avail_out-n,i=t.strstart-t.block_start,a>i+t.strm.avail_in&&(a=i+t.strm.avail_in),a>n&&(a=n),a<s&&(0===a&&e!==X||e===P||a!==i+t.strm.avail_in))break;r=e===X&&a===i+t.strm.avail_in?1:0,H(t,0,0,r),t.pending_buf[t.pending-4]=a,t.pending_buf[t.pending-3]=a>>8,t.pending_buf[t.pending-2]=~a,t.pending_buf[t.pending-1]=~a>>8,ct(t.strm),i&&(i>a&&(i=a),t.strm.output.set(t.window.subarray(t.block_start,t.block_start+i),t.strm.next_out),t.strm.next_out+=i,t.strm.avail_out-=i,t.strm.total_out+=i,t.block_start+=i,a-=i),a&&(bt(t.strm,t.strm.output,t.strm.next_out,a),t.strm.next_out+=a,t.strm.avail_out-=a,t.strm.total_out+=a);}while(0===r);return l-=t.strm.avail_in,l&&(l>=t.w_size?(t.matches=2,t.window.set(t.strm.input.subarray(t.strm.next_in-t.w_size,t.strm.next_in),0),t.strstart=t.w_size,t.insert=t.strstart):(t.window_size-t.strstart<=l&&(t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,t.insert>t.strstart&&(t.insert=t.strstart)),t.window.set(t.strm.input.subarray(t.strm.next_in-l,t.strm.next_in),t.strstart),t.strstart+=l,t.insert+=l>t.w_size-t.insert?t.w_size-t.insert:l),t.block_start=t.strstart),t.high_water<t.strstart&&(t.high_water=t.strstart),r?4:e!==P&&e!==X&&0===t.strm.avail_in&&t.strstart===t.block_start?2:(n=t.window_size-t.strstart,t.strm.avail_in>n&&t.block_start>=t.w_size&&(t.block_start-=t.w_size,t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,n+=t.w_size,t.insert>t.strstart&&(t.insert=t.strstart)),n>t.strm.avail_in&&(n=t.strm.avail_in),n&&(bt(t.strm,t.window,t.strstart,n),t.strstart+=n,t.insert+=n>t.w_size-t.insert?t.w_size-t.insert:n),t.high_water<t.strstart&&(t.high_water=t.strstart),n=t.bi_valid+42>>3,n=t.pending_buf_size-n>65535?65535:t.pending_buf_size-n,s=n>t.w_size?t.w_size:n,i=t.strstart-t.block_start,(i>=s||(i||e===X)&&e!==P&&0===t.strm.avail_in&&i<=n)&&(a=i>n?n:i,r=e===X&&0===t.strm.avail_in&&a===i?1:0,H(t,t.block_start,a,r),t.block_start+=a,ct(t.strm)),r?3:1)},vt=(t,e)=>{let a,i;for(;;){if(t.lookahead<262){if(pt(t),t.lookahead<262&&e===P)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=ft(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==a&&t.strstart-a<=t.w_size-262&&(t.match_length=gt(t,a)),t.match_length>=3)if(i=j(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=ft(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart;}while(0!=--t.match_length);t.strstart++;}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=ft(t,t.ins_h,t.window[t.strstart+1]);else i=j(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(ut(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===X?(ut(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(ut(t,!1),0===t.strm.avail_out)?1:2},yt=(t,e)=>{let a,i,n;for(;;){if(t.lookahead<262){if(pt(t),t.lookahead<262&&e===P)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=ft(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==a&&t.prev_length<t.max_lazy_match&&t.strstart-a<=t.w_size-262&&(t.match_length=gt(t,a),t.match_length<=5&&(t.strategy===et||3===t.match_length&&t.strstart-t.match_start>4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=j(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=ft(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart);}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(ut(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=j(t,0,t.window[t.strstart-1]),i&&ut(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--;}return t.match_available&&(i=j(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===X?(ut(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(ut(t,!1),0===t.strm.avail_out)?1:2};function xt(t,e,a,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=a,this.max_chain=i,this.func=n;}const zt=[new xt(0,0,0,0,kt),new xt(4,4,8,4,vt),new xt(4,5,16,8,vt),new xt(4,6,32,32,vt),new xt(4,4,16,16,yt),new xt(8,16,32,32,yt),new xt(8,16,128,128,yt),new xt(8,32,128,256,yt),new xt(32,128,258,1024,yt),new xt(32,258,258,4096,yt)];function At(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=lt,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),dt(this.dyn_ltree),dt(this.dyn_dtree),dt(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),dt(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),dt(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0;}const Et=t=>{if(!t)return 1;const e=t.state;return !e||e.strm!==t||42!==e.status&&57!==e.status&&69!==e.status&&73!==e.status&&91!==e.status&&103!==e.status&&113!==e.status&&666!==e.status?1:0},Rt=t=>{if(Et(t))return ot(t,Q);t.total_in=t.total_out=0,t.data_type=rt;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=2===e.wrap?57:e.wrap?42:113,t.adler=2===e.wrap?0:1,e.last_flush=-2,C(e),q},Zt=t=>{const e=Rt(t);var a;return e===q&&((a=t.state).window_size=2*a.w_size,dt(a.head),a.max_lazy_match=zt[a.level].max_lazy,a.good_match=zt[a.level].good_length,a.nice_match=zt[a.level].nice_length,a.max_chain_length=zt[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=2,a.match_available=0,a.ins_h=0),e},Ut=(t,e,a,i,n,s)=>{if(!t)return Q;let r=1;if(e===tt&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||a!==lt||i<8||i>15||e<0||e>9||s<0||s>nt||8===i&&1!==r)return ot(t,Q);8===i&&(i=9);const l=new At;return t.state=l,l.strm=t,l.status=42,l.wrap=r,l.gzhead=null,l.w_bits=i,l.w_size=1<<l.w_bits,l.w_mask=l.w_size-1,l.hash_bits=n+7,l.hash_size=1<<l.hash_bits,l.hash_mask=l.hash_size-1,l.hash_shift=~~((l.hash_bits+3-1)/3),l.window=new Uint8Array(2*l.w_size),l.head=new Uint16Array(l.hash_size),l.prev=new Uint16Array(l.w_size),l.lit_bufsize=1<<n+6,l.pending_buf_size=4*l.lit_bufsize,l.pending_buf=new Uint8Array(l.pending_buf_size),l.sym_buf=l.lit_bufsize,l.sym_end=3*(l.lit_bufsize-1),l.level=e,l.strategy=s,l.method=a,Zt(t)};var St={deflateInit:(t,e)=>Ut(t,e,lt,15,8,st),deflateInit2:Ut,deflateReset:Zt,deflateResetKeep:Rt,deflateSetHeader:(t,e)=>Et(t)||2!==t.state.wrap?Q:(t.state.gzhead=e,q),deflate:(t,e)=>{if(Et(t)||e>W||e<0)return t?ot(t,Q):Q;const a=t.state;if(!t.output||0!==t.avail_in&&!t.input||666===a.status&&e!==X)return ot(t,0===t.avail_out?$:Q);const i=a.last_flush;if(a.last_flush=e,0!==a.pending){if(ct(t),0===t.avail_out)return a.last_flush=-1,q}else if(0===t.avail_in&&ht(e)<=ht(i)&&e!==X)return ot(t,$);if(666===a.status&&0!==t.avail_in)return ot(t,$);if(42===a.status&&0===a.wrap&&(a.status=113),42===a.status){let e=lt+(a.w_bits-8<<4)<<8,i=-1;if(i=a.strategy>=at||a.level<2?0:a.level<6?1:6===a.level?2:3,e|=i<<6,0!==a.strstart&&(e|=32),e+=31-e%31,mt(a,e),0!==a.strstart&&(mt(a,t.adler>>>16),mt(a,65535&t.adler)),t.adler=1,a.status=113,ct(t),0!==a.pending)return a.last_flush=-1,q}if(57===a.status)if(t.adler=0,wt(a,31),wt(a,139),wt(a,8),a.gzhead)wt(a,(a.gzhead.text?1:0)+(a.gzhead.hcrc?2:0)+(a.gzhead.extra?4:0)+(a.gzhead.name?8:0)+(a.gzhead.comment?16:0)),wt(a,255&a.gzhead.time),wt(a,a.gzhead.time>>8&255),wt(a,a.gzhead.time>>16&255),wt(a,a.gzhead.time>>24&255),wt(a,9===a.level?2:a.strategy>=at||a.level<2?4:0),wt(a,255&a.gzhead.os),a.gzhead.extra&&a.gzhead.extra.length&&(wt(a,255&a.gzhead.extra.length),wt(a,a.gzhead.extra.length>>8&255)),a.gzhead.hcrc&&(t.adler=L(t.adler,a.pending_buf,a.pending,0)),a.gzindex=0,a.status=69;else if(wt(a,0),wt(a,0),wt(a,0),wt(a,0),wt(a,0),wt(a,9===a.level?2:a.strategy>=at||a.level<2?4:0),wt(a,3),a.status=113,ct(t),0!==a.pending)return a.last_flush=-1,q;if(69===a.status){if(a.gzhead.extra){let e=a.pending,i=(65535&a.gzhead.extra.length)-a.gzindex;for(;a.pending+i>a.pending_buf_size;){let n=a.pending_buf_size-a.pending;if(a.pending_buf.set(a.gzhead.extra.subarray(a.gzindex,a.gzindex+n),a.pending),a.pending=a.pending_buf_size,a.gzhead.hcrc&&a.pending>e&&(t.adler=L(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex+=n,ct(t),0!==a.pending)return a.last_flush=-1,q;e=0,i-=n;}let n=new Uint8Array(a.gzhead.extra);a.pending_buf.set(n.subarray(a.gzindex,a.gzindex+i),a.pending),a.pending+=i,a.gzhead.hcrc&&a.pending>e&&(t.adler=L(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex=0;}a.status=73;}if(73===a.status){if(a.gzhead.name){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=L(t.adler,a.pending_buf,a.pending-i,i)),ct(t),0!==a.pending)return a.last_flush=-1,q;i=0;}e=a.gzindex<a.gzhead.name.length?255&a.gzhead.name.charCodeAt(a.gzindex++):0,wt(a,e);}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=L(t.adler,a.pending_buf,a.pending-i,i)),a.gzindex=0;}a.status=91;}if(91===a.status){if(a.gzhead.comment){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=L(t.adler,a.pending_buf,a.pending-i,i)),ct(t),0!==a.pending)return a.last_flush=-1,q;i=0;}e=a.gzindex<a.gzhead.comment.length?255&a.gzhead.comment.charCodeAt(a.gzindex++):0,wt(a,e);}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=L(t.adler,a.pending_buf,a.pending-i,i));}a.status=103;}if(103===a.status){if(a.gzhead.hcrc){if(a.pending+2>a.pending_buf_size&&(ct(t),0!==a.pending))return a.last_flush=-1,q;wt(a,255&t.adler),wt(a,t.adler>>8&255),t.adler=0;}if(a.status=113,ct(t),0!==a.pending)return a.last_flush=-1,q}if(0!==t.avail_in||0!==a.lookahead||e!==P&&666!==a.status){let i=0===a.level?kt(a,e):a.strategy===at?((t,e)=>{let a;for(;;){if(0===t.lookahead&&(pt(t),0===t.lookahead)){if(e===P)return 1;break}if(t.match_length=0,a=j(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,a&&(ut(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===X?(ut(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(ut(t,!1),0===t.strm.avail_out)?1:2})(a,e):a.strategy===it?((t,e)=>{let a,i,n,s;const r=t.window;for(;;){if(t.lookahead<=258){if(pt(t),t.lookahead<=258&&e===P)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){s=t.strstart+258;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&n<s);t.match_length=258-(s-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead);}if(t.match_length>=3?(a=j(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(a=j(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),a&&(ut(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===X?(ut(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(ut(t,!1),0===t.strm.avail_out)?1:2})(a,e):zt[a.level].func(a,e);if(3!==i&&4!==i||(a.status=666),1===i||3===i)return 0===t.avail_out&&(a.last_flush=-1),q;if(2===i&&(e===Y?K(a):e!==W&&(H(a,0,0,!1),e===G&&(dt(a.head),0===a.lookahead&&(a.strstart=0,a.block_start=0,a.insert=0))),ct(t),0===t.avail_out))return a.last_flush=-1,q}return e!==X?q:a.wrap<=0?J:(2===a.wrap?(wt(a,255&t.adler),wt(a,t.adler>>8&255),wt(a,t.adler>>16&255),wt(a,t.adler>>24&255),wt(a,255&t.total_in),wt(a,t.total_in>>8&255),wt(a,t.total_in>>16&255),wt(a,t.total_in>>24&255)):(mt(a,t.adler>>>16),mt(a,65535&t.adler)),ct(t),a.wrap>0&&(a.wrap=-a.wrap),0!==a.pending?q:J)},deflateEnd:t=>{if(Et(t))return Q;const e=t.state.status;return t.state=null,113===e?ot(t,V):q},deflateSetDictionary:(t,e)=>{let a=e.length;if(Et(t))return Q;const i=t.state,n=i.wrap;if(2===n||1===n&&42!==i.status||i.lookahead)return Q;if(1===n&&(t.adler=I(t.adler,e,a,0)),i.wrap=0,a>=i.w_size){0===n&&(dt(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(a-i.w_size,a),0),e=t,a=i.w_size;}const s=t.avail_in,r=t.next_in,l=t.input;for(t.avail_in=a,t.next_in=0,t.input=e,pt(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=ft(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++;}while(--e);i.strstart=t,i.lookahead=2,pt(i);}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=l,t.avail_in=s,i.wrap=n,q},deflateInfo:"pako deflate (from Nodeca project)"};const Dt=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var Tt=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const a=e.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(const e in a)Dt(a,e)&&(t[e]=a[e]);}}return t},Ot=t=>{let e=0;for(let a=0,i=t.length;a<i;a++)e+=t[a].length;const a=new Uint8Array(e);for(let e=0,i=0,n=t.length;e<n;e++){let n=t[e];a.set(n,i),i+=n.length;}return a};let It=!0;try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(t){It=!1;}const Ft=new Uint8Array(256);for(let t=0;t<256;t++)Ft[t]=t>=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;Ft[254]=Ft[254]=1;var Lt=t=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return (new TextEncoder).encode(t);let e,a,i,n,s,r=t.length,l=0;for(n=0;n<r;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),l+=a<128?1:a<2048?2:a<65536?3:4;for(e=new Uint8Array(l),s=0,n=0;s<l;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),a<128?e[s++]=a:a<2048?(e[s++]=192|a>>>6,e[s++]=128|63&a):a<65536?(e[s++]=224|a>>>12,e[s++]=128|a>>>6&63,e[s++]=128|63&a):(e[s++]=240|a>>>18,e[s++]=128|a>>>12&63,e[s++]=128|a>>>6&63,e[s++]=128|63&a);return e},Nt=(t,e)=>{const a=e||t.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return (new TextDecoder).decode(t.subarray(0,e));let i,n;const s=new Array(2*a);for(n=0,i=0;i<a;){let e=t[i++];if(e<128){s[n++]=e;continue}let r=Ft[e];if(r>4)s[n++]=65533,i+=r-1;else {for(e&=2===r?31:3===r?15:7;r>1&&i<a;)e=e<<6|63&t[i++],r--;r>1?s[n++]=65533:e<65536?s[n++]=e:(e-=65536,s[n++]=55296|e>>10&1023,s[n++]=56320|1023&e);}}return ((t,e)=>{if(e<65534&&t.subarray&&It)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let a="";for(let i=0;i<e;i++)a+=String.fromCharCode(t[i]);return a})(s,n)},Bt=(t,e)=>{(e=e||t.length)>t.length&&(e=t.length);let a=e-1;for(;a>=0&&128==(192&t[a]);)a--;return a<0||0===a?e:a+Ft[t[a]]>e?a:e};var Ct=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};const Ht=Object.prototype.toString,{Z_NO_FLUSH:Mt,Z_SYNC_FLUSH:jt,Z_FULL_FLUSH:Kt,Z_FINISH:Pt,Z_OK:Yt,Z_STREAM_END:Gt,Z_DEFAULT_COMPRESSION:Xt,Z_DEFAULT_STRATEGY:Wt,Z_DEFLATED:qt}=B;function Jt(t){this.options=Tt({level:Xt,method:qt,chunkSize:16384,windowBits:15,memLevel:8,strategy:Wt},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Ct,this.strm.avail_out=0;let a=St.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==Yt)throw new Error(N[a]);if(e.header&&St.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t="string"==typeof e.dictionary?Lt(e.dictionary):"[object ArrayBuffer]"===Ht.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,a=St.deflateSetDictionary(this.strm,t),a!==Yt)throw new Error(N[a]);this._dict_set=!0;}}Jt.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize;let n,s;if(this.ended)return !1;for(s=e===~~e?e:!0===e?Pt:Mt,"string"==typeof t?a.input=Lt(t):"[object ArrayBuffer]"===Ht.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;)if(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),(s===jt||s===Kt)&&a.avail_out<=6)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else {if(n=St.deflate(a,s),n===Gt)return a.next_out>0&&this.onData(a.output.subarray(0,a.next_out)),n=St.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===Yt;if(0!==a.avail_out){if(s>0&&a.next_out>0)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else if(0===a.avail_in)break}else this.onData(a.output);}return !0},Jt.prototype.onData=function(t){this.chunks.push(t);},Jt.prototype.onEnd=function(t){t===Yt&&(this.result=Ot(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg;};var $t=function(t,e){let a,i,n,s,r,l,o,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z,A;const E=t.state;a=t.next_in,z=t.input,i=a+(t.avail_in-5),n=t.next_out,A=t.output,s=n-(e-t.avail_out),r=n+(t.avail_out-257),l=E.dmax,o=E.wsize,h=E.whave,d=E.wnext,_=E.window,f=E.hold,c=E.bits,u=E.lencode,w=E.distcode,m=(1<<E.lenbits)-1,b=(1<<E.distbits)-1;t:do{c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=u[f&m];e:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,0===p)A[n++]=65535&g;else {if(!(16&p)){if(0==(64&p)){g=u[(65535&g)+(f&(1<<p)-1)];continue e}if(32&p){E.mode=16191;break t}t.msg="invalid literal/length code",E.mode=16209;break t}k=65535&g,p&=15,p&&(c<p&&(f+=z[a++]<<c,c+=8),k+=f&(1<<p)-1,f>>>=p,c-=p),c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=w[f&b];a:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,!(16&p)){if(0==(64&p)){g=w[(65535&g)+(f&(1<<p)-1)];continue a}t.msg="invalid distance code",E.mode=16209;break t}if(v=65535&g,p&=15,c<p&&(f+=z[a++]<<c,c+=8,c<p&&(f+=z[a++]<<c,c+=8)),v+=f&(1<<p)-1,v>l){t.msg="invalid distance too far back",E.mode=16209;break t}if(f>>>=p,c-=p,p=n-s,v>p){if(p=v-p,p>h&&E.sane){t.msg="invalid distance too far back",E.mode=16209;break t}if(y=0,x=_,0===d){if(y+=o-p,p<k){k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}}else if(d<p){if(y+=o+d-p,p-=d,p<k){k-=p;do{A[n++]=_[y++];}while(--p);if(y=0,d<k){p=d,k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}}}else if(y+=d-p,p<k){k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}for(;k>2;)A[n++]=x[y++],A[n++]=x[y++],A[n++]=x[y++],k-=3;k&&(A[n++]=x[y++],k>1&&(A[n++]=x[y++]));}else {y=n-v;do{A[n++]=A[y++],A[n++]=A[y++],A[n++]=A[y++],k-=3;}while(k>2);k&&(A[n++]=A[y++],k>1&&(A[n++]=A[y++]));}break}}break}}while(a<i&&n<r);k=c>>3,a-=k,c-=k<<3,f&=(1<<c)-1,t.next_in=a,t.next_out=n,t.avail_in=a<i?i-a+5:5-(a-i),t.avail_out=n<r?r-n+257:257-(n-r),E.hold=f,E.bits=c;};const te=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0]),ee=new Uint8Array([16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78]),ae=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0]),ie=new Uint8Array([16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64]);var ne=(t,e,a,i,n,s,r,l)=>{const o=l.bits;let h,d,_,f,c,u,w=0,m=0,b=0,g=0,p=0,k=0,v=0,y=0,x=0,z=0,A=null;const E=new Uint16Array(16),R=new Uint16Array(16);let Z,U,S,D=null;for(w=0;w<=15;w++)E[w]=0;for(m=0;m<i;m++)E[e[a+m]]++;for(p=o,g=15;g>=1&&0===E[g];g--);if(p>g&&(p=g),0===g)return n[s++]=20971520,n[s++]=20971520,l.bits=1,0;for(b=1;b<g&&0===E[b];b++);for(p<b&&(p=b),y=1,w=1;w<=15;w++)if(y<<=1,y-=E[w],y<0)return -1;if(y>0&&(0===t||1!==g))return -1;for(R[1]=0,w=1;w<15;w++)R[w+1]=R[w]+E[w];for(m=0;m<i;m++)0!==e[a+m]&&(r[R[e[a+m]]++]=m);if(0===t?(A=D=r,u=20):1===t?(A=te,D=ee,u=257):(A=ae,D=ie,u=0),z=0,m=0,w=b,c=s,k=p,v=0,_=-1,x=1<<p,f=x-1,1===t&&x>852||2===t&&x>592)return 1;for(;;){Z=w-v,r[m]+1<u?(U=0,S=r[m]):r[m]>=u?(U=D[r[m]-u],S=A[r[m]-u]):(U=96,S=0),h=1<<w-v,d=1<<k,b=d;do{d-=h,n[c+(z>>v)+d]=Z<<24|U<<16|S|0;}while(0!==d);for(h=1<<w-1;z&h;)h>>=1;if(0!==h?(z&=h-1,z+=h):z=0,m++,0==--E[w]){if(w===g)break;w=e[a+r[m]];}if(w>p&&(z&f)!==_){for(0===v&&(v=p),c+=b,k=w-v,y=1<<k;k+v<g&&(y-=E[k+v],!(y<=0));)k++,y<<=1;if(x+=1<<k,1===t&&x>852||2===t&&x>592)return 1;_=z&f,n[_]=p<<24|k<<16|c-s|0;}}return 0!==z&&(n[c+z]=w-v<<24|64<<16|0),l.bits=p,0};const{Z_FINISH:se,Z_BLOCK:re,Z_TREES:le,Z_OK:oe,Z_STREAM_END:he,Z_NEED_DICT:de,Z_STREAM_ERROR:_e,Z_DATA_ERROR:fe,Z_MEM_ERROR:ce,Z_BUF_ERROR:ue,Z_DEFLATED:we}=B,me=16209,be=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function ge(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}const pe=t=>{if(!t)return 1;const e=t.state;return !e||e.strm!==t||e.mode<16180||e.mode>16211?1:0},ke=t=>{if(pe(t))return _e;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=16180,e.last=0,e.havedict=0,e.flags=-1,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,oe},ve=t=>{if(pe(t))return _e;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,ke(t)},ye=(t,e)=>{let a;if(pe(t))return _e;const i=t.state;return e<0?(a=0,e=-e):(a=5+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?_e:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=a,i.wbits=e,ve(t))},xe=(t,e)=>{if(!t)return _e;const a=new ge;t.state=a,a.strm=t,a.window=null,a.mode=16180;const i=ye(t,e);return i!==oe&&(t.state=null),i};let ze,Ae,Ee=!0;const Re=t=>{if(Ee){ze=new Int32Array(512),Ae=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(ne(1,t.lens,0,288,ze,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;ne(2,t.lens,0,32,Ae,0,t.work,{bits:5}),Ee=!1;}t.lencode=ze,t.lenbits=9,t.distcode=Ae,t.distbits=5;},Ze=(t,e,a,i)=>{let n;const s=t.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new Uint8Array(s.wsize)),i>=s.wsize?(s.window.set(e.subarray(a-s.wsize,a),0),s.wnext=0,s.whave=s.wsize):(n=s.wsize-s.wnext,n>i&&(n=i),s.window.set(e.subarray(a-i,a-i+n),s.wnext),(i-=n)?(s.window.set(e.subarray(a-i,a),0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=n))),0};var Ue={inflateReset:ve,inflateReset2:ye,inflateResetKeep:ke,inflateInit:t=>xe(t,15),inflateInit2:xe,inflate:(t,e)=>{let a,i,n,s,r,l,o,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z=0;const A=new Uint8Array(4);let E,R;const Z=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(pe(t)||!t.output||!t.input&&0!==t.avail_in)return _e;a=t.state,16191===a.mode&&(a.mode=16192),r=t.next_out,n=t.output,o=t.avail_out,s=t.next_in,i=t.input,l=t.avail_in,h=a.hold,d=a.bits,_=l,f=o,x=oe;t:for(;;)switch(a.mode){case 16180:if(0===a.wrap){a.mode=16192;break}for(;d<16;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(2&a.wrap&&35615===h){0===a.wbits&&(a.wbits=15),a.check=0,A[0]=255&h,A[1]=h>>>8&255,a.check=L(a.check,A,2,0),h=0,d=0,a.mode=16181;break}if(a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&h)<<8)+(h>>8))%31){t.msg="incorrect header check",a.mode=me;break}if((15&h)!==we){t.msg="unknown compression method",a.mode=me;break}if(h>>>=4,d-=4,y=8+(15&h),0===a.wbits&&(a.wbits=y),y>15||y>a.wbits){t.msg="invalid window size",a.mode=me;break}a.dmax=1<<a.wbits,a.flags=0,t.adler=a.check=1,a.mode=512&h?16189:16191,h=0,d=0;break;case 16181:for(;d<16;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(a.flags=h,(255&a.flags)!==we){t.msg="unknown compression method",a.mode=me;break}if(57344&a.flags){t.msg="unknown header flags set",a.mode=me;break}a.head&&(a.head.text=h>>8&1),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=L(a.check,A,2,0)),h=0,d=0,a.mode=16182;case 16182:for(;d<32;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.head&&(a.head.time=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,A[2]=h>>>16&255,A[3]=h>>>24&255,a.check=L(a.check,A,4,0)),h=0,d=0,a.mode=16183;case 16183:for(;d<16;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.head&&(a.head.xflags=255&h,a.head.os=h>>8),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=L(a.check,A,2,0)),h=0,d=0,a.mode=16184;case 16184:if(1024&a.flags){for(;d<16;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.length=h,a.head&&(a.head.extra_len=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=L(a.check,A,2,0)),h=0,d=0;}else a.head&&(a.head.extra=null);a.mode=16185;case 16185:if(1024&a.flags&&(c=a.length,c>l&&(c=l),c&&(a.head&&(y=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Uint8Array(a.head.extra_len)),a.head.extra.set(i.subarray(s,s+c),y)),512&a.flags&&4&a.wrap&&(a.check=L(a.check,i,c,s)),l-=c,s+=c,a.length-=c),a.length))break t;a.length=0,a.mode=16186;case 16186:if(2048&a.flags){if(0===l)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.name+=String.fromCharCode(y));}while(y&&c<l);if(512&a.flags&&4&a.wrap&&(a.check=L(a.check,i,c,s)),l-=c,s+=c,y)break t}else a.head&&(a.head.name=null);a.length=0,a.mode=16187;case 16187:if(4096&a.flags){if(0===l)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.comment+=String.fromCharCode(y));}while(y&&c<l);if(512&a.flags&&4&a.wrap&&(a.check=L(a.check,i,c,s)),l-=c,s+=c,y)break t}else a.head&&(a.head.comment=null);a.mode=16188;case 16188:if(512&a.flags){for(;d<16;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(4&a.wrap&&h!==(65535&a.check)){t.msg="header crc mismatch",a.mode=me;break}h=0,d=0;}a.head&&(a.head.hcrc=a.flags>>9&1,a.head.done=!0),t.adler=a.check=0,a.mode=16191;break;case 16189:for(;d<32;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}t.adler=a.check=be(h),h=0,d=0,a.mode=16190;case 16190:if(0===a.havedict)return t.next_out=r,t.avail_out=o,t.next_in=s,t.avail_in=l,a.hold=h,a.bits=d,de;t.adler=a.check=1,a.mode=16191;case 16191:if(e===re||e===le)break t;case 16192:if(a.last){h>>>=7&d,d-=7&d,a.mode=16206;break}for(;d<3;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}switch(a.last=1&h,h>>>=1,d-=1,3&h){case 0:a.mode=16193;break;case 1:if(Re(a),a.mode=16199,e===le){h>>>=2,d-=2;break t}break;case 2:a.mode=16196;break;case 3:t.msg="invalid block type",a.mode=me;}h>>>=2,d-=2;break;case 16193:for(h>>>=7&d,d-=7&d;d<32;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if((65535&h)!=(h>>>16^65535)){t.msg="invalid stored block lengths",a.mode=me;break}if(a.length=65535&h,h=0,d=0,a.mode=16194,e===le)break t;case 16194:a.mode=16195;case 16195:if(c=a.length,c){if(c>l&&(c=l),c>o&&(c=o),0===c)break t;n.set(i.subarray(s,s+c),r),l-=c,s+=c,o-=c,r+=c,a.length-=c;break}a.mode=16191;break;case 16196:for(;d<14;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(a.nlen=257+(31&h),h>>>=5,d-=5,a.ndist=1+(31&h),h>>>=5,d-=5,a.ncode=4+(15&h),h>>>=4,d-=4,a.nlen>286||a.ndist>30){t.msg="too many length or distance symbols",a.mode=me;break}a.have=0,a.mode=16197;case 16197:for(;a.have<a.ncode;){for(;d<3;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.lens[Z[a.have++]]=7&h,h>>>=3,d-=3;}for(;a.have<19;)a.lens[Z[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,E={bits:a.lenbits},x=ne(0,a.lens,0,19,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid code lengths set",a.mode=me;break}a.have=0,a.mode=16198;case 16198:for(;a.have<a.nlen+a.ndist;){for(;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(g<16)h>>>=m,d-=m,a.lens[a.have++]=g;else {if(16===g){for(R=m+2;d<R;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(h>>>=m,d-=m,0===a.have){t.msg="invalid bit length repeat",a.mode=me;break}y=a.lens[a.have-1],c=3+(3&h),h>>>=2,d-=2;}else if(17===g){for(R=m+3;d<R;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}h>>>=m,d-=m,y=0,c=3+(7&h),h>>>=3,d-=3;}else {for(R=m+7;d<R;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}h>>>=m,d-=m,y=0,c=11+(127&h),h>>>=7,d-=7;}if(a.have+c>a.nlen+a.ndist){t.msg="invalid bit length repeat",a.mode=me;break}for(;c--;)a.lens[a.have++]=y;}}if(a.mode===me)break;if(0===a.lens[256]){t.msg="invalid code -- missing end-of-block",a.mode=me;break}if(a.lenbits=9,E={bits:a.lenbits},x=ne(1,a.lens,0,a.nlen,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid literal/lengths set",a.mode=me;break}if(a.distbits=6,a.distcode=a.distdyn,E={bits:a.distbits},x=ne(2,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,E),a.distbits=E.bits,x){t.msg="invalid distances set",a.mode=me;break}if(a.mode=16199,e===le)break t;case 16199:a.mode=16200;case 16200:if(l>=6&&o>=258){t.next_out=r,t.avail_out=o,t.next_in=s,t.avail_in=l,a.hold=h,a.bits=d,$t(t,f),r=t.next_out,n=t.output,o=t.avail_out,s=t.next_in,i=t.input,l=t.avail_in,h=a.hold,d=a.bits,16191===a.mode&&(a.back=-1);break}for(a.back=0;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(b&&0==(240&b)){for(p=m,k=b,v=g;z=a.lencode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}h>>>=p,d-=p,a.back+=p;}if(h>>>=m,d-=m,a.back+=m,a.length=g,0===b){a.mode=16205;break}if(32&b){a.back=-1,a.mode=16191;break}if(64&b){t.msg="invalid literal/length code",a.mode=me;break}a.extra=15&b,a.mode=16201;case 16201:if(a.extra){for(R=a.extra;d<R;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.length+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra;}a.was=a.length,a.mode=16202;case 16202:for(;z=a.distcode[h&(1<<a.distbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(0==(240&b)){for(p=m,k=b,v=g;z=a.distcode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}h>>>=p,d-=p,a.back+=p;}if(h>>>=m,d-=m,a.back+=m,64&b){t.msg="invalid distance code",a.mode=me;break}a.offset=g,a.extra=15&b,a.mode=16203;case 16203:if(a.extra){for(R=a.extra;d<R;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}a.offset+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra;}if(a.offset>a.dmax){t.msg="invalid distance too far back",a.mode=me;break}a.mode=16204;case 16204:if(0===o)break t;if(c=f-o,a.offset>c){if(c=a.offset-c,c>a.whave&&a.sane){t.msg="invalid distance too far back",a.mode=me;break}c>a.wnext?(c-=a.wnext,u=a.wsize-c):u=a.wnext-c,c>a.length&&(c=a.length),w=a.window;}else w=n,u=r-a.offset,c=a.length;c>o&&(c=o),o-=c,a.length-=c;do{n[r++]=w[u++];}while(--c);0===a.length&&(a.mode=16200);break;case 16205:if(0===o)break t;n[r++]=a.length,o--,a.mode=16200;break;case 16206:if(a.wrap){for(;d<32;){if(0===l)break t;l--,h|=i[s++]<<d,d+=8;}if(f-=o,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?L(a.check,n,f,r-f):I(a.check,n,f,r-f)),f=o,4&a.wrap&&(a.flags?h:be(h))!==a.check){t.msg="incorrect data check",a.mode=me;break}h=0,d=0;}a.mode=16207;case 16207:if(a.wrap&&a.flags){for(;d<32;){if(0===l)break t;l--,h+=i[s++]<<d,d+=8;}if(4&a.wrap&&h!==(4294967295&a.total)){t.msg="incorrect length check",a.mode=me;break}h=0,d=0;}a.mode=16208;case 16208:x=he;break t;case me:x=fe;break t;case 16210:return ce;default:return _e}return t.next_out=r,t.avail_out=o,t.next_in=s,t.avail_in=l,a.hold=h,a.bits=d,(a.wsize||f!==t.avail_out&&a.mode<me&&(a.mode<16206||e!==se))&&Ze(t,t.output,t.next_out,f-t.avail_out),_-=t.avail_in,f-=t.avail_out,t.total_in+=_,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?L(a.check,n,f,t.next_out-f):I(a.check,n,f,t.next_out-f)),t.data_type=a.bits+(a.last?64:0)+(16191===a.mode?128:0)+(16199===a.mode||16194===a.mode?256:0),(0===_&&0===f||e===se)&&x===oe&&(x=ue),x},inflateEnd:t=>{if(pe(t))return _e;let e=t.state;return e.window&&(e.window=null),t.state=null,oe},inflateGetHeader:(t,e)=>{if(pe(t))return _e;const a=t.state;return 0==(2&a.wrap)?_e:(a.head=e,e.done=!1,oe)},inflateSetDictionary:(t,e)=>{const a=e.length;let i,n,s;return pe(t)?_e:(i=t.state,0!==i.wrap&&16190!==i.mode?_e:16190===i.mode&&(n=1,n=I(n,e,a,0),n!==i.check)?fe:(s=Ze(t,e,a,a),s?(i.mode=16210,ce):(i.havedict=1,oe)))},inflateInfo:"pako inflate (from Nodeca project)"};var Se=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1;};const De=Object.prototype.toString,{Z_NO_FLUSH:Te,Z_FINISH:Oe,Z_OK:Ie,Z_STREAM_END:Fe,Z_NEED_DICT:Le,Z_STREAM_ERROR:Ne,Z_DATA_ERROR:Be,Z_MEM_ERROR:Ce}=B;function He(t){this.options=Tt({chunkSize:65536,windowBits:15,to:""},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Ct,this.strm.avail_out=0;let a=Ue.inflateInit2(this.strm,e.windowBits);if(a!==Ie)throw new Error(N[a]);if(this.header=new Se,Ue.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=Lt(e.dictionary):"[object ArrayBuffer]"===De.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(a=Ue.inflateSetDictionary(this.strm,e.dictionary),a!==Ie)))throw new Error(N[a])}He.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let s,r,l;if(this.ended)return !1;for(r=e===~~e?e:!0===e?Oe:Te,"[object ArrayBuffer]"===De.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;){for(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),s=Ue.inflate(a,r),s===Le&&n&&(s=Ue.inflateSetDictionary(a,n),s===Ie?s=Ue.inflate(a,r):s===Be&&(s=Le));a.avail_in>0&&s===Fe&&a.state.wrap>0&&0!==t[a.next_in];)Ue.inflateReset(a),s=Ue.inflate(a,r);switch(s){case Ne:case Be:case Le:case Ce:return this.onEnd(s),this.ended=!0,!1}if(l=a.avail_out,a.next_out&&(0===a.avail_out||s===Fe))if("string"===this.options.to){let t=Bt(a.output,a.next_out),e=a.next_out-t,n=Nt(a.output,t);a.next_out=e,a.avail_out=i-e,e&&a.output.set(a.output.subarray(t,t+e),0),this.onData(n);}else this.onData(a.output.length===a.next_out?a.output:a.output.subarray(0,a.next_out));if(s!==Ie||0!==l){if(s===Fe)return s=Ue.inflateEnd(this.strm),this.onEnd(s),this.ended=!0,!0;if(0===a.avail_in)break}}return !0},He.prototype.onData=function(t){this.chunks.push(t);},He.prototype.onEnd=function(t){t===Ie&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Ot(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg;};

var checkOutDisk;
//****************************************************************************
//:Helper functions:
//****************************************************************************
{
	
	//------------------------------------------------------------------------
	var checkOutDiskAndApplyChanges=async function(diskName,diskVO,sync,tty){
		let tabFS$1=tabFS;
		let files,i,n,filePath,basePath,data,path;
		
		basePath="/"+diskName+"/";
		//First, check out base version:
		await checkOutDisk(tty,diskVO.diskId,diskVO.versionIdx,diskName,sync);
		if(!diskVO.files){
			return;
		}
		//Remove files:
		try{
			files=diskVO.deleteItems||[];
			n=files.length;
			for(i=0;i<n;i++){
				await tabFS$1.del(basePath+files[i]);
			}
		}catch(err){
		}
		//Add new dirs:
		try{
			files=diskVO.newDirs||[];
			n=files.length;
			for(i=0;i<n;i++){
				await tabFS$1.newDir(basePath+files[i]);
			}
		}catch(err){
		}
		//Apply files:
		try{
			files=diskVO.datas||{};
			for(filePath in files){
				path=basePath+filePath;
				data=files[filePath];
				data=Base64.decode(data);
				await tabFS$1.writeFile(path,data);
			}
		}catch(err){
		}
	};
}

//****************************************************************************
//:Sandbox related functions:
//****************************************************************************
{
	
	//------------------------------------------------------------------------
	var restoreSandbox=async function(tty,zipData){
		let tabFS$1=tabFS;
		let diskZips,zip,diskTag,diskName,diskVO,data,encoder,sync;
		diskZips={};
		if(tty){
			tty.textOut("Reading zip...");
		}
		zip=await JSZip$1.loadAsync(zipData);
		zip.forEach((path,zipObj)=>{
			diskZips[path]=zipObj;
		});
		
		for(diskTag in diskZips){
			data=await diskZips[diskTag].async("uint8array");
			if(diskTag.endsWith(".zip")){
				diskName=diskTag.substring(0,diskTag.length-4);
				/*if(diskName==="coke")*/{
					await tabFS$1.openDisk(diskName,true);
					zip2NewPath("/"+diskName,data,tty);
				}
			}else if(diskTag.endsWith(".json")){
				diskName=diskTag.substring(0,diskTag.length-5);
				sync=(diskName[0]==="-")?false:true;
				/*if(diskName==="pkg"||diskName==="-files")*/{
					encoder = new TextDecoder("utf-8");
					diskVO=encoder.decode(data);
					diskVO=JSON.parse(diskVO);
					await checkOutDiskAndApplyChanges(diskName,diskVO,sync,tty);
				}
			}
		}
	};
}

//****************************************************************************
//:Cloud disk related functions:
//****************************************************************************
{

	//------------------------------------------------------------------------
	//:Check out a disk into the path
	checkOutDisk=async function(tty,diskId,versionIdx,diskName,sync=true){
		let diskObj,resDiskVO,zipData,diskJSON,buff;
		let files,path;
		let logger;
		logger={};
		logger.log=tty?function(text){
			tty.textOut(text+"\n");
		}:function(){};
	
		try{
			resDiskVO=await theCokeNT.makeCall("diskCheckOut",{"diskId":diskId,"versionIdx":versionIdx});
		}catch(err){
			logger.log("API call error: "+err);
			throw(err);
		}
		if(resDiskVO.code!==200){
			logger.log("Download error "+resDiskVO.code+": "+resDiskVO.info);
			throw "Check out disk error "+resDiskVO.code+": "+resDiskVO.info;
		}
		logger.log("Disk data downloaded. ");
		logger.log("Create local disk.");
		diskJSON=JSON.parse(resDiskVO.diskJSON);
		zipData=resDiskVO.zipData;
		versionIdx=resDiskVO.versionIdx;
		buff=Base64.decode(zipData);

		diskObj=await tabFS.openDisk(diskName,1);
		if(!diskObj){
			logger.log("Create disk error");
			throw "Create disk error";
		}

		logger.log("Extract disk zip image on local disk.");
		await zip2Path("/"+diskName,buff,0,tty);
		logger.log("Extract disk zip image done.");

		if(sync){
			logger.log("Save disk info.");
			await tabFS.setDiskInfo(diskName,diskJSON);
			await tabFS.setDiskAttr(diskName,"versionIdx",versionIdx);
			logger.log("Save disk info done.");

			logger.log("Update local files version info.");
			files=diskJSON.files;
			for(path in files){
				await diskObj.setEntryInfo(path,{baseVersionIdx:versionIdx,modified:0});
			}
			logger.log("Update local files version info done.");
		}else {
			try{
				diskJSON=await diskObj.readFile("disk.json","utf8");
				if(diskJSON){
					diskJSON=JSON.parse(diskJSON);
					delete diskJSON.cloudId;
					delete diskJSON.version;
					delete diskJSON.versionIdx;
					await diskObj.writeFile("disk.json",JSON.stringify(diskJSON,null,"\t"),"utf8");			
				}
			}catch(err){
			}
		}
		return true;
	};
}

//Auto genterated by Cody
/*}#1GFLQJK0D0StartDoc*/
appCfg.lanCode||VFACT.lanCode||"EN";
//----------------------------------------------------------------------------
let MainUI=function(app){
	let cssVO,self;
	appCfg.lanCode||VFACT.lanCode||"EN";
	
	let title="Multiverse for Developers";
	let caption="Setup Tab-OS";
	
	/*#{1GFLQJK0D1LocalVals*/
	let dataSetup=null;
	let tty=null;
	let appParams=app.appParams;
	let hostName,domain,pos;
	hostName=domain=document.location.hostname;
	pos=domain.indexOf(":");
	if(pos>0){
		domain="";//With port number?
	}else {
		pos=domain.indexOf(".");
		if(pos>0){
			domain=domain.substring(0,pos);
		}else {
			domain="";
		}
	}
	if(appCfg.isPreview){
		if(hostName==="pv.ai2apps.com"){
			title="AI2Apps App Preview";
		}else {
			title="Tab-OS App Preview";
		}
		caption="Setup preview...";
	}else if(domain==="www"||!domain){
		if(hostName.endsWith("ai2apps.com")){
			title="AI2Apps.com";
			caption="Setup AI2Apps...";
		}else {
			title="Multiverse for Developers";
			caption="Setup Tab-OS Home Universe";
		}
	}else {
		title="Universe Portal: "+domain.toUpperCase();
		caption="Setup Universe";
	}
	/*}#1GFLQJK0D1LocalVals*/
	
	/*#{1GFLQJK0D1PreState*/
	dataSetup=new DataSetup();
	/*}#1GFLQJK0D1PreState*/
	/*#{1GFLQJK0D1PostState*/
	/*}#1GFLQJK0D1PostState*/
	cssVO={
		"hash":"1GFLQJK0D1",nameHost:true,
		"type":"view","x":0,"y":0,"w":"FW","h":"FH","autoLayout":true,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
		children:[
			{
				"hash":"1GG1LG6II0",
				"type":"text","id":"TxtTitle","x":"FW/2","y":15,"w":"FW>=500?500:FW-10","h":24,"anchorX":1,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
				"color":[120,120,130],"text":title,"fontSize":24,"fontWeight":"bold","fontStyle":"normal","textDecoration":"",
			},
			{
				"hash":"1GFLTI4GC0",
				"type":"box","x":"FW/2","y":50,"w":"FW>=500?500:FW-10","h":"FH>660?600:FH-60","anchorX":1,"overflow":1,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
				"background":[255,255,255,1],"border":2,"corner":6,
				children:[
					{
						"hash":"1GFLTTKRI0",
						"type":"box","id":"BoxHeader","x":0,"y":0,"w":"FW","h":24,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","background":"linear-gradient(to bottom, rgba(220,220,220,1),rgba(200,200,200,1))",
						"border":[0,0,1,0],
						children:[
							{
								"hash":"1GFLU4DC30",
								"type":"box","x":5,"y":4,"w":16,"h":16,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","background":[245,245,245,1],"border":1,"corner":9,
							},
							{
								"hash":"1GFLU6CFN0",
								"type":"box","x":23,"y":4,"w":16,"h":16,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","background":[245,245,245,1],"border":1,"corner":9,
							},
							{
								"hash":"1GFLU6HPD0",
								"type":"box","x":41,"y":4,"w":16,"h":16,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","background":[245,245,245,1],"border":1,"corner":9,
							},
							{
								"hash":"1GFLU72L70",
								"type":"text","id":"TxtCaption","x":62,"y":0,"w":"","h":"FH","minW":"","minH":"","maxW":"","maxH":"","styleClass":"","color":[50,50,50],"text":caption,
								"fontSize":15,"fontWeight":"normal","fontStyle":"normal","textDecoration":"","alignV":1,
							}
						],
					},
					{
						"hash":"1GFLUAVAR0",
						"type":"hud","id":"BoxTTY","x":5,"y":24,"w":"FW-10","h":"FH-29","minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
					},
					{
						"hash":"1GKJRQNAK0",
						"type":"hud","id":"BoxRestoreFile","x":5,"y":24,"w":"FW-10","h":"FH-29","minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
						children:[
							{
								"hash":"1GKJS0SDA0",
								"type":"box","id":"BoxDrop","x":"30","y":30,"w":"FW-60","h":150,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","background":[255,255,255,1],
								"border":2,"borderStyle":2,"corner":6,
								children:[
									{
										"hash":"1GKJS0SDB0",
										"type":"text","x":0,"y":0,"w":"FW","h":"FH","uiEvent":-1,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","color":[0,0,0],"text":"Drag Universe Zip File Here",
										"fontSize":20,"fontWeight":"normal","fontStyle":"normal","textDecoration":"","alignH":1,"alignV":1,
									}
								],
								/*#{1GKJS0SDA0Codes*/
								/*}#1GKJS0SDA0Codes*/
							},
							{
								"hash":"1GKJS1TIK0",
								"type":"text","x":0,"y":200,"w":"FW","h":20,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","color":[0,0,0],"text":"OR","fontSize":20,
								"fontWeight":"normal","fontStyle":"normal","textDecoration":"","alignH":1,
							},
							{
								"hash":"1GKJSO0PF0",
								"type":"button","x":"FW/2","y":240,"w":240,"h":30,"anchorX":1,"cursor":"pointer","minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
								children:[
									{
										"hash":"1GKJSP42O0",
										"type":"box","id":"BtnOpen","x":"FW/2","y":0,"w":240,"h":30,"anchorX":1,"uiEvent":-1,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"",
										"background":[42,124,255,1],"corner":3,
										children:[
											{
												"hash":"1GKJSP42P0",
												"type":"text","x":0,"y":0,"w":"FW","h":"FH","autoLayout":true,"uiEvent":-1,"minW":"","minH":"","maxW":"","maxH":"","styleClass":"","color":[255,255,255],
												"text":"Choose Universe Zip File","fontWeight":"normal","fontStyle":"normal","textDecoration":"","alignH":1,"alignV":1,
											}
										],
									}
								],
								/*#{1GKJSO0PF0Codes*/
								"labelHtml": '<input type="file" multiple="false" style="width:0px">',
								OnLableAction:function(){
									let files=this.files,n;
									n=files.length;
									if(n>0){
										self.restoreSandbox(files[0]);
									}
									this.value="";
								}
								/*}#1GKJSO0PF0Codes*/
							}
						],
					}
				],
			}
		],
		/*#{1GFLQJK0D1ExtraCSS*/
		/*}#1GFLQJK0D1ExtraCSS*/
		faces:{
			"work":{
				/*BoxTTY*/"#1GFLUAVAR0":{
					"display":1
				},
				/*BoxRestoreFile*/"#1GKJRQNAK0":{
					"display":0
				}
			},"file":{
				/*BoxTTY*/"#1GFLUAVAR0":{
					"display":0
				},
				/*BoxRestoreFile*/"#1GKJRQNAK0":{
					"display":1
				}
			}
		},
		OnCreate:function(){
			self=this;
			
			/*#{1GFLQJK0D1Create*/
			tty=new LitTTY(self.BoxTTY.webObj,null);
			self.showFace("work");
			if(appParams.reinstall);else if(appParams.clear){
				self.maybeClear();
			}else if(appParams.osimage){
				if(window.confirm("Install a Tab-OS Universe image will clean up current universe data, are you sure?")){
					self.maybeClear().then(()=>{
						if(appParams.osimage==="file"){
							self.applyDrop();
							self.showFace("file");
						}
					});
				}
			}else {
				self.maybeInstall();
			}
			/*}#1GFLQJK0D1Create*/
		},
		/*#{1GFLQJK0D1EndCSS*/
		/*}#1GFLQJK0D1EndCSS*/
	};
	/*#{1GFLQJK0D1PostCSSVO*/
	//------------------------------------------------------------------------
	cssVO.maybeInstall=async function(){
		let checkVersion;
		if(appCfg.isPreview){
			checkVersion=false;
		}else if(appCfg.isMobile){
			checkVersion=true;
		}else {
			checkVersion=false;
		}
		if(!await dataSetup.checkOS(tty,checkVersion)){
			await dataSetup.setupOS(tty);
		}
		tty.log("Tab-OS installed, will launch Tab-OS Home...");
		//Wait service worker...
		window.setTimeout(()=>{
			self.openOS();
	},1000);
	};
	
	//------------------------------------------------------------------------
	cssVO.maybeClear=async function(){
		if(!await dataSetup.checkOS(tty)){
			if(window.confirm("Can't find installed Tab-OS. Clear Tab-OS related resource anyway?")){
				await dataSetup.clearOS(tty);
			}
		}else {
			if(window.confirm("Installed Tab-OS detected. Are you sure clear Tab-OS related resource anyway? You may lose un-backuped data.")){
				await dataSetup.clearOS(tty);
			}
		}
	};
	
	//------------------------------------------------------------------------
	cssVO.maybeInstallImage=async function(type){
		//TODO: Code this:
	};
	
	//------------------------------------------------------------------------
	cssVO.openOS=function(){
		if(appCfg.isSetupApps){
			document.location.href = document.location.origin + `/~/-MobileHome/app.html?app=${appCfg.appId}`;
		}else if(appCfg.isPreview){
			if(VFACT.appParams.userId){
				document.location.href = document.location.origin + `/~/-PVHome/app.html?userId=${VFACT.appParams.userId}&slot=${VFACT.appParams.slot}&key=${VFACT.appParams.key}`;
			}else if(location.host.startsWith("pv.")){
				document.location.href = document.location.origin + `/~/-PVHome/app.html`;
			}
		}else if(appParams.path){
			document.location.href=document.location.origin+appParams.path;
		}else if(location.host.startsWith("pv.")){
			document.location.href = document.location.origin + `/~/-PVHome/app.html`;
		}else {
			if(appParams.app){
				document.location.href = document.location.origin + `/@homekit?app=${appParams.app}`;
			}else {
				document.location.href = document.location.origin + "/@homekit";
			}
		}
	};
	
	//************************************************************************
	//Sandbox
	//************************************************************************
	{
		//--------------------------------------------------------------------
		cssVO.applyDrop=function(){
			let webObj;
			let dragging=0;
			webObj=self.BoxDrop.webObj;
			VFACT.applyDrop(self,{
				OnDragEnter(evt){
					if(evt.target===webObj){
						[...evt.dataTransfer.types];
						dragging=1;
						evt.dataTransfer.dropEffect="copy";
						evt.preventDefault();
						evt.stopPropagation();
						self.showFace("over");
					}
				},
				OnDragOver(evt){
					if(dragging && evt.target===webObj){
						evt.dataTransfer.dropEffect="copy";
						evt.stopPropagation();
						evt.preventDefault();
					}
				},
				OnDragLeave(evt){
					if(evt.target===webObj){
						dragging=0;
						self.showFace("out");
					}
				},
				OnDrop(evt){
					if(dragging){
						let dt=evt.dataTransfer;
						self.doCopyDataTransferFiles(dt);
						evt.preventDefault();
						evt.stopPropagation();
					}
				}
			});
		};
		
		//--------------------------------------------------------------------
		cssVO.doCopyDataTransferFiles=async function(dt){
			let items,entry,path,fileObj;
	
			function getItemFile(item){
				return new Promise((OnDone,OnError)=>{
					item.file(OnDone);
				});
			}
	
			items=dt.items;
			if(items.length<1){
				return;
			}
			if(items.length>1){
				window.alert("Only one file allowed!");
				return;
			}
			entry=items[0].webkitGetAsEntry();
			if(!entry.isFile){
				window.alert("Only zip-file is allowed!");
				return;
			}
			path=entry.fullPath;
			if(!path.toLowerCase().endsWith(".zip")){
				window.alert("Only zip-file is allowed!");
				return;
			}
			fileObj=await getItemFile(entry);
			await self.restoreSandbox(fileObj);
		};
		
		//--------------------------------------------------------------------
		cssVO.restoreSandbox=async function(fileObj){
			let buff;
			
			async function arrayBuffer(file){
				if(file.arrayBuffer){
					return file.arrayBuffer();
				}
				return new Promise((onDone,onError)=>{
					let reader=new FileReader();
					reader.onload=function(event) {
						let arrayBuffer = event.target.result;
						onDone(arrayBuffer);
					};
					reader.readAsArrayBuffer(file);
				})
			}
	
			self.showFace("work");
			buff=await arrayBuffer(fileObj);
			await dataSetup.installWorker(tty);
			await restoreSandbox(tty,buff);
			//Wait a while...
			window.setTimeout(()=>{
				self.openOS();
			},500);
		};
	}
	/*}#1GFLQJK0D1PostCSSVO*/
	return cssVO;
};
/*Cody Project Doc*/
//{
//	"type": "docfile",
//	"def": "UIView",
//	"jaxId": "1GFLQJK0D0",
//	"attrs": {
//		"editEnv": {
//			"jaxId": "1GFLQJK0E0",
//			"attrs": {
//				"device": "Custom Size",
//				"screenW": "800",
//				"screenH": "750",
//				"bgColor": "[255,255,255]",
//				"bgChecker": "false"
//			}
//		},
//		"editObjs": {
//			"jaxId": "1GFLQJK0E1",
//			"attrs": {}
//		},
//		"model": {
//			"jaxId": "1HGTK4CSE0",
//			"attrs": {}
//		},
//		"createArgs": {
//			"jaxId": "1GFLQJK0E2",
//			"attrs": {
//				"app": {
//					"type": "auto",
//					"valText": "null"
//				}
//			}
//		},
//		"localVars": {
//			"jaxId": "1GFLQJK0E3",
//			"attrs": {
//				"title": {
//					"type": "string",
//					"valText": "Multiverse for Developers"
//				},
//				"caption": {
//					"type": "string",
//					"valText": "Setup Tab-OS"
//				}
//			}
//		},
//		"oneHud": "false",
//		"state": {
//			"jaxId": "1GFLQJK0E4",
//			"attrs": {}
//		},
//		"segs": {
//			"attrs": []
//		},
//		"exportTarget": "\"jax\"",
//		"gearName": "",
//		"gearIcon": "gears.svg",
//		"gearW": "100",
//		"gearH": "100",
//		"gearCatalog": "",
//		"description": "",
//		"fixPose": "false",
//		"previewImg": "",
//		"faceTags": {
//			"jaxId": "1GFLQJK0E5",
//			"attrs": {
//				"work": {
//					"type": "facetag",
//					"def": "FaceTag",
//					"jaxId": "1GKKF1QFQ0",
//					"attrs": {
//						"mockup": "false",
//						"previewEntry": "false",
//						"mockupNext": "",
//						"description": "",
//						"preFunc": "false",
//						"faceFunc": "false",
//						"delay": "0",
//						"faceTimes": {
//							"jaxId": "1GKKF4F6V0",
//							"attrs": {}
//						}
//					}
//				},
//				"file": {
//					"type": "facetag",
//					"def": "FaceTag",
//					"jaxId": "1GKKF2JUU0",
//					"attrs": {
//						"mockup": "false",
//						"previewEntry": "false",
//						"mockupNext": "",
//						"description": "",
//						"preFunc": "false",
//						"faceFunc": "false",
//						"delay": "0",
//						"faceTimes": {
//							"jaxId": "1GKKF4F6V1",
//							"attrs": {}
//						}
//					}
//				}
//			}
//		},
//		"mockupStates": {
//			"jaxId": "1HGTK4CSE1",
//			"attrs": {}
//		},
//		"hud": {
//			"type": "hudobj",
//			"def": "view",
//			"jaxId": "1GFLQJK0D1",
//			"attrs": {
//				"properties": {
//					"jaxId": "1GFLQJK0E6",
//					"attrs": {
//						"type": "view",
//						"id": "",
//						"position": "Absolute",
//						"x": "0",
//						"y": "0",
//						"w": "\"FW\"",
//						"h": "\"FH\"",
//						"anchorH": "Left",
//						"anchorV": "Top",
//						"autoLayout": "true",
//						"display": "On",
//						"clip": "Off",
//						"uiEvent": "On",
//						"alpha": "1",
//						"rotate": "0",
//						"scale": "",
//						"filter": "",
//						"cursor": "",
//						"zIndex": "0",
//						"margin": "",
//						"padding": "",
//						"minW": "",
//						"minH": "",
//						"maxW": "",
//						"maxH": "",
//						"face": "",
//						"styleClass": ""
//					}
//				},
//				"subHuds": {
//					"attrs": [
//						{
//							"type": "hudobj",
//							"def": "text",
//							"jaxId": "1GG1LG6II0",
//							"attrs": {
//								"properties": {
//									"jaxId": "1GG1LRFDF0",
//									"attrs": {
//										"type": "text",
//										"id": "TxtTitle",
//										"position": "Absolute",
//										"x": "\"FW/2\"",
//										"y": "15",
//										"w": "\"FW>=500?500:FW-10\"",
//										"h": "24",
//										"anchorH": "Center",
//										"anchorV": "Top",
//										"autoLayout": "false",
//										"display": "On",
//										"clip": "Off",
//										"uiEvent": "On",
//										"alpha": "1",
//										"rotate": "0",
//										"scale": "",
//										"filter": "",
//										"cursor": "",
//										"zIndex": "0",
//										"margin": "",
//										"padding": "",
//										"minW": "",
//										"minH": "",
//										"maxW": "",
//										"maxH": "",
//										"face": "",
//										"styleClass": "",
//										"color": "[120,120,130]",
//										"text": "#title",
//										"font": "",
//										"fontSize": "24",
//										"bold": "true",
//										"italic": "false",
//										"underline": "false",
//										"alignH": "Left",
//										"alignV": "Top",
//										"wrap": "false",
//										"ellipsis": "false",
//										"select": "false",
//										"shadow": "false",
//										"shadowX": "0",
//										"shadowY": "2",
//										"shadowBlur": "3",
//										"shadowColor": "[0,0,0,1.00]",
//										"shadowEx": "",
//										"maxTextW": "0",
//										"autoSizeW": "false",
//										"autoSizeH": "false"
//									}
//								},
//								"subHuds": {
//									"attrs": []
//								},
//								"faces": {
//									"jaxId": "1GG1LRFDF1",
//									"attrs": {
//										"1GKKF2JUU0": {
//											"type": "hudface",
//											"def": "HudFace",
//											"jaxId": "1GKKF4F6V4",
//											"attrs": {
//												"properties": {
//													"jaxId": "1GKKF4F6V5",
//													"attrs": {}
//												},
//												"anis": {
//													"attrs": []
//												}
//											},
//											"faceTagId": "1GKKF2JUU0",
//											"faceTagName": "file"
//										}
//									}
//								},
//								"functions": {
//									"jaxId": "1GG1LRFDF2",
//									"attrs": {}
//								},
//								"extraPpts": {
//									"jaxId": "1GG1LRFDF3",
//									"attrs": {}
//								},
//								"mockup": "false",
//								"codes": "false",
//								"locked": "false",
//								"container": "false",
//								"nameVal": "false"
//							}
//						},
//						{
//							"type": "hudobj",
//							"def": "box",
//							"jaxId": "1GFLTI4GC0",
//							"attrs": {
//								"properties": {
//									"jaxId": "1GFLUN3O60",
//									"attrs": {
//										"type": "box",
//										"id": "",
//										"position": "Absolute",
//										"x": "\"FW/2\"",
//										"y": "50",
//										"w": "\"FW>=500?500:FW-10\"",
//										"h": "\"FH>660?600:FH-60\"",
//										"anchorH": "Center",
//										"anchorV": "Top",
//										"autoLayout": "false",
//										"display": "On",
//										"clip": "On",
//										"uiEvent": "On",
//										"alpha": "1",
//										"rotate": "0",
//										"scale": "",
//										"filter": "",
//										"cursor": "",
//										"zIndex": "0",
//										"margin": "",
//										"padding": "",
//										"minW": "",
//										"minH": "",
//										"maxW": "",
//										"maxH": "",
//										"face": "",
//										"styleClass": "",
//										"background": "[255,255,255,1.00]",
//										"border": "2",
//										"borderStyle": "Solid",
//										"borderColor": "[0,0,0,1.00]",
//										"corner": "6",
//										"shadow": "false",
//										"shadowX": "2",
//										"shadowY": "2",
//										"shadowBlur": "3",
//										"shadowSpread": "0",
//										"shadowColor": "[0,0,0,0.50]"
//									}
//								},
//								"subHuds": {
//									"attrs": [
//										{
//											"type": "hudobj",
//											"def": "box",
//											"jaxId": "1GFLTTKRI0",
//											"attrs": {
//												"properties": {
//													"jaxId": "1GFLTTKRI1",
//													"attrs": {
//														"type": "box",
//														"id": "BoxHeader",
//														"position": "Absolute",
//														"x": "0",
//														"y": "0",
//														"w": "\"FW\"",
//														"h": "24",
//														"anchorH": "Left",
//														"anchorV": "Top",
//														"autoLayout": "false",
//														"display": "On",
//														"clip": "Off",
//														"uiEvent": "On",
//														"alpha": "1",
//														"rotate": "0",
//														"scale": "",
//														"filter": "",
//														"cursor": "",
//														"zIndex": "0",
//														"margin": "",
//														"padding": "",
//														"minW": "",
//														"minH": "",
//														"maxW": "",
//														"maxH": "",
//														"face": "",
//														"styleClass": "",
//														"background": "linear-gradient(to bottom, rgba(220,220,220,1),rgba(200,200,200,1))",
//														"border": "[0,0,1,0]",
//														"borderStyle": "Solid",
//														"borderColor": "[0,0,0,1.00]",
//														"corner": "0",
//														"shadow": "false",
//														"shadowX": "2",
//														"shadowY": "2",
//														"shadowBlur": "3",
//														"shadowSpread": "0",
//														"shadowColor": "[0,0,0,0.50]"
//													}
//												},
//												"subHuds": {
//													"attrs": [
//														{
//															"type": "hudobj",
//															"def": "box",
//															"jaxId": "1GFLU4DC30",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GFLU5KUR0",
//																	"attrs": {
//																		"type": "box",
//																		"id": "",
//																		"position": "Absolute",
//																		"x": "5",
//																		"y": "4",
//																		"w": "16",
//																		"h": "16",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"background": "[245,245,245,1.00]",
//																		"border": "1",
//																		"borderStyle": "Solid",
//																		"borderColor": "[0,0,0,1.00]",
//																		"corner": "9",
//																		"shadow": "false",
//																		"shadowX": "2",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowSpread": "0",
//																		"shadowColor": "[0,0,0,0.50]"
//																	}
//																},
//																"subHuds": {
//																	"attrs": []
//																},
//																"faces": {
//																	"jaxId": "1GFLU5KUS0",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F6V8",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F6V9",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GFLU5KUS1",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GFLU5KUS2",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "false",
//																"locked": "false",
//																"container": "true",
//																"nameVal": "false"
//															}
//														},
//														{
//															"type": "hudobj",
//															"def": "box",
//															"jaxId": "1GFLU6CFN0",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GFLU6CFN1",
//																	"attrs": {
//																		"type": "box",
//																		"id": "",
//																		"position": "Absolute",
//																		"x": "23",
//																		"y": "4",
//																		"w": "16",
//																		"h": "16",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"background": "[245,245,245,1.00]",
//																		"border": "1",
//																		"borderStyle": "Solid",
//																		"borderColor": "[0,0,0,1.00]",
//																		"corner": "9",
//																		"shadow": "false",
//																		"shadowX": "2",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowSpread": "0",
//																		"shadowColor": "[0,0,0,0.50]"
//																	}
//																},
//																"subHuds": {
//																	"attrs": []
//																},
//																"faces": {
//																	"jaxId": "1GFLU6CFO0",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F6V12",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F6V13",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GFLU6CFO1",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GFLU6CFO2",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "false",
//																"locked": "false",
//																"container": "true",
//																"nameVal": "false"
//															}
//														},
//														{
//															"type": "hudobj",
//															"def": "box",
//															"jaxId": "1GFLU6HPD0",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GFLU6HPD1",
//																	"attrs": {
//																		"type": "box",
//																		"id": "",
//																		"position": "Absolute",
//																		"x": "41",
//																		"y": "4",
//																		"w": "16",
//																		"h": "16",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"background": "[245,245,245,1.00]",
//																		"border": "1",
//																		"borderStyle": "Solid",
//																		"borderColor": "[0,0,0,1.00]",
//																		"corner": "9",
//																		"shadow": "false",
//																		"shadowX": "2",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowSpread": "0",
//																		"shadowColor": "[0,0,0,0.50]"
//																	}
//																},
//																"subHuds": {
//																	"attrs": []
//																},
//																"faces": {
//																	"jaxId": "1GFLU6HPD2",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F6V16",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F6V17",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GFLU6HPD3",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GFLU6HPD4",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "false",
//																"locked": "false",
//																"container": "true",
//																"nameVal": "false"
//															}
//														},
//														{
//															"type": "hudobj",
//															"def": "text",
//															"jaxId": "1GFLU72L70",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GFLUN3O61",
//																	"attrs": {
//																		"type": "text",
//																		"id": "TxtCaption",
//																		"position": "Absolute",
//																		"x": "62",
//																		"y": "0",
//																		"w": "\"\"",
//																		"h": "\"FH\"",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"color": "[50,50,50]",
//																		"text": "#caption",
//																		"font": "",
//																		"fontSize": "15",
//																		"bold": "false",
//																		"italic": "false",
//																		"underline": "false",
//																		"alignH": "Left",
//																		"alignV": "Center",
//																		"wrap": "false",
//																		"ellipsis": "false",
//																		"select": "false",
//																		"shadow": "false",
//																		"shadowX": "0",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowColor": "[0,0,0,1.00]",
//																		"shadowEx": "",
//																		"maxTextW": "0",
//																		"autoSizeW": "false",
//																		"autoSizeH": "false"
//																	}
//																},
//																"subHuds": {
//																	"attrs": []
//																},
//																"faces": {
//																	"jaxId": "1GFLUN3O62",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F6V20",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F6V21",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GFLUN3O63",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GFLUN3O64",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "false",
//																"locked": "false",
//																"container": "false",
//																"nameVal": "false"
//															}
//														}
//													]
//												},
//												"faces": {
//													"jaxId": "1GFLTTKRJ0",
//													"attrs": {
//														"1GKKF2JUU0": {
//															"type": "hudface",
//															"def": "HudFace",
//															"jaxId": "1GKKF4F6V24",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKKF4F6V25",
//																	"attrs": {}
//																},
//																"anis": {
//																	"attrs": []
//																}
//															},
//															"faceTagId": "1GKKF2JUU0",
//															"faceTagName": "file"
//														}
//													}
//												},
//												"functions": {
//													"jaxId": "1GFLTTKRJ1",
//													"attrs": {}
//												},
//												"extraPpts": {
//													"jaxId": "1GFLTTKRJ2",
//													"attrs": {}
//												},
//												"mockup": "false",
//												"codes": "false",
//												"locked": "false",
//												"container": "true",
//												"nameVal": "false"
//											}
//										},
//										{
//											"type": "hudobj",
//											"def": "hud",
//											"jaxId": "1GFLUAVAR0",
//											"attrs": {
//												"properties": {
//													"jaxId": "1GFLUAVAR1",
//													"attrs": {
//														"type": "hud",
//														"id": "BoxTTY",
//														"position": "Absolute",
//														"x": "5",
//														"y": "24",
//														"w": "\"FW-10\"",
//														"h": "\"FH-29\"",
//														"anchorH": "Left",
//														"anchorV": "Top",
//														"autoLayout": "false",
//														"display": "On",
//														"clip": "Off",
//														"uiEvent": "On",
//														"alpha": "1",
//														"rotate": "0",
//														"scale": "",
//														"filter": "",
//														"cursor": "",
//														"zIndex": "0",
//														"margin": "",
//														"padding": "",
//														"minW": "",
//														"minH": "",
//														"maxW": "",
//														"maxH": "",
//														"face": "",
//														"styleClass": ""
//													}
//												},
//												"subHuds": {
//													"attrs": []
//												},
//												"faces": {
//													"jaxId": "1GFLUAVAR2",
//													"attrs": {
//														"1GKKF1QFQ0": {
//															"type": "hudface",
//															"def": "HudFace",
//															"jaxId": "1GKKF4F6V26",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKKF4F6V27",
//																	"attrs": {
//																		"display": {
//																			"type": "choice",
//																			"valText": "On"
//																		}
//																	}
//																},
//																"anis": {
//																	"attrs": []
//																}
//															},
//															"faceTagId": "1GKKF1QFQ0",
//															"faceTagName": "work"
//														},
//														"1GKKF2JUU0": {
//															"type": "hudface",
//															"def": "HudFace",
//															"jaxId": "1GKKF4F6V28",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKKF4F6V29",
//																	"attrs": {
//																		"display": {
//																			"type": "choice",
//																			"valText": "Off"
//																		}
//																	}
//																},
//																"anis": {
//																	"attrs": []
//																}
//															},
//															"faceTagId": "1GKKF2JUU0",
//															"faceTagName": "file"
//														}
//													}
//												},
//												"functions": {
//													"jaxId": "1GFLUAVAR3",
//													"attrs": {}
//												},
//												"extraPpts": {
//													"jaxId": "1GFLUAVAR4",
//													"attrs": {}
//												},
//												"mockup": "false",
//												"codes": "false",
//												"locked": "false",
//												"container": "true",
//												"nameVal": "false",
//												"exposeContainer": "false"
//											}
//										},
//										{
//											"type": "hudobj",
//											"def": "hud",
//											"jaxId": "1GKJRQNAK0",
//											"attrs": {
//												"properties": {
//													"jaxId": "1GKJRQNAK1",
//													"attrs": {
//														"type": "hud",
//														"id": "BoxRestoreFile",
//														"position": "Absolute",
//														"x": "5",
//														"y": "24",
//														"w": "\"FW-10\"",
//														"h": "\"FH-29\"",
//														"anchorH": "Left",
//														"anchorV": "Top",
//														"autoLayout": "false",
//														"display": "On",
//														"clip": "Off",
//														"uiEvent": "On",
//														"alpha": "1",
//														"rotate": "0",
//														"scale": "",
//														"filter": "",
//														"cursor": "",
//														"zIndex": "0",
//														"margin": "",
//														"padding": "",
//														"minW": "",
//														"minH": "",
//														"maxW": "",
//														"maxH": "",
//														"face": "",
//														"styleClass": ""
//													}
//												},
//												"subHuds": {
//													"attrs": [
//														{
//															"type": "hudobj",
//															"def": "box",
//															"jaxId": "1GKJS0SDA0",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKJS0SDA1",
//																	"attrs": {
//																		"type": "box",
//																		"id": "BoxDrop",
//																		"position": "Absolute",
//																		"x": "\"30\"",
//																		"y": "30",
//																		"w": "\"FW-60\"",
//																		"h": "150",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"background": "[255,255,255,1.00]",
//																		"border": "2",
//																		"borderStyle": "Dashed",
//																		"borderColor": "[0,0,0,1.00]",
//																		"corner": "6",
//																		"shadow": "false",
//																		"shadowX": "2",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowSpread": "0",
//																		"shadowColor": "[0,0,0,0.50]"
//																	}
//																},
//																"subHuds": {
//																	"attrs": [
//																		{
//																			"type": "hudobj",
//																			"def": "text",
//																			"jaxId": "1GKJS0SDB0",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKJS0SDB1",
//																					"attrs": {
//																						"type": "text",
//																						"id": "",
//																						"position": "Absolute",
//																						"x": "0",
//																						"y": "0",
//																						"w": "\"FW\"",
//																						"h": "\"FH\"",
//																						"anchorH": "Left",
//																						"anchorV": "Top",
//																						"autoLayout": "false",
//																						"display": "On",
//																						"clip": "Off",
//																						"uiEvent": "Tree Off",
//																						"alpha": "1",
//																						"rotate": "0",
//																						"scale": "",
//																						"filter": "",
//																						"cursor": "",
//																						"zIndex": "0",
//																						"margin": "",
//																						"padding": "",
//																						"minW": "",
//																						"minH": "",
//																						"maxW": "",
//																						"maxH": "",
//																						"face": "",
//																						"styleClass": "",
//																						"color": "[0,0,0]",
//																						"text": "Drag Universe Zip File Here",
//																						"font": "",
//																						"fontSize": "20",
//																						"bold": "false",
//																						"italic": "false",
//																						"underline": "false",
//																						"alignH": "Center",
//																						"alignV": "Center",
//																						"wrap": "false",
//																						"ellipsis": "false",
//																						"select": "false",
//																						"shadow": "false",
//																						"shadowX": "0",
//																						"shadowY": "2",
//																						"shadowBlur": "3",
//																						"shadowColor": "[0,0,0,1.00]",
//																						"shadowEx": "",
//																						"maxTextW": "0",
//																						"autoSizeW": "false",
//																						"autoSizeH": "false"
//																					}
//																				},
//																				"subHuds": {
//																					"attrs": []
//																				},
//																				"faces": {
//																					"jaxId": "1GKJS0SDB2",
//																					"attrs": {
//																						"1GKKF2JUU0": {
//																							"type": "hudface",
//																							"def": "HudFace",
//																							"jaxId": "1GKKF4F6V32",
//																							"attrs": {
//																								"properties": {
//																									"jaxId": "1GKKF4F6V33",
//																									"attrs": {}
//																								},
//																								"anis": {
//																									"attrs": []
//																								}
//																							},
//																							"faceTagId": "1GKKF2JUU0",
//																							"faceTagName": "file"
//																						}
//																					}
//																				},
//																				"functions": {
//																					"jaxId": "1GKJS0SDB3",
//																					"attrs": {}
//																				},
//																				"extraPpts": {
//																					"jaxId": "1GKJS0SDB4",
//																					"attrs": {}
//																				},
//																				"mockup": "false",
//																				"codes": "false",
//																				"locked": "false",
//																				"container": "false",
//																				"nameVal": "false"
//																			}
//																		}
//																	]
//																},
//																"faces": {
//																	"jaxId": "1GKJS0SDB5",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F6V36",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F6V37",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GKJS0SDB6",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GKJS0SDB7",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "true",
//																"locked": "false",
//																"container": "true",
//																"nameVal": "false"
//															}
//														},
//														{
//															"type": "hudobj",
//															"def": "text",
//															"jaxId": "1GKJS1TIK0",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKJSB86L0",
//																	"attrs": {
//																		"type": "text",
//																		"id": "",
//																		"position": "Absolute",
//																		"x": "0",
//																		"y": "200",
//																		"w": "\"FW\"",
//																		"h": "20",
//																		"anchorH": "Left",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"color": "[0,0,0]",
//																		"text": "OR",
//																		"font": "",
//																		"fontSize": "20",
//																		"bold": "false",
//																		"italic": "false",
//																		"underline": "false",
//																		"alignH": "Center",
//																		"alignV": "Top",
//																		"wrap": "false",
//																		"ellipsis": "false",
//																		"select": "false",
//																		"shadow": "false",
//																		"shadowX": "0",
//																		"shadowY": "2",
//																		"shadowBlur": "3",
//																		"shadowColor": "[0,0,0,1.00]",
//																		"shadowEx": "",
//																		"maxTextW": "0",
//																		"autoSizeW": "false",
//																		"autoSizeH": "false"
//																	}
//																},
//																"subHuds": {
//																	"attrs": []
//																},
//																"faces": {
//																	"jaxId": "1GKJSB86L1",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F702",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F703",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GKJSB86L2",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GKJSB86L3",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "false",
//																"locked": "false",
//																"container": "false",
//																"nameVal": "false"
//															}
//														},
//														{
//															"type": "hudobj",
//															"def": "button",
//															"jaxId": "1GKJSO0PF0",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKJSO0PG0",
//																	"attrs": {
//																		"type": "button",
//																		"id": "",
//																		"position": "Absolute",
//																		"x": "\"FW/2\"",
//																		"y": "240",
//																		"w": "240",
//																		"h": "30",
//																		"anchorH": "Center",
//																		"anchorV": "Top",
//																		"autoLayout": "false",
//																		"display": "On",
//																		"clip": "Off",
//																		"uiEvent": "On",
//																		"alpha": "1",
//																		"rotate": "0",
//																		"scale": "",
//																		"filter": "",
//																		"cursor": "pointer",
//																		"zIndex": "0",
//																		"margin": "",
//																		"padding": "",
//																		"minW": "",
//																		"minH": "",
//																		"maxW": "",
//																		"maxH": "",
//																		"face": "",
//																		"styleClass": "",
//																		"enable": "true",
//																		"drag": "NA"
//																	}
//																},
//																"subHuds": {
//																	"attrs": [
//																		{
//																			"type": "hudobj",
//																			"def": "box",
//																			"jaxId": "1GKJSP42O0",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKJSP42O1",
//																					"attrs": {
//																						"type": "box",
//																						"id": "BtnOpen",
//																						"position": "Absolute",
//																						"x": "\"FW/2\"",
//																						"y": "0",
//																						"w": "240",
//																						"h": "30",
//																						"anchorH": "Center",
//																						"anchorV": "Top",
//																						"autoLayout": "false",
//																						"display": "On",
//																						"clip": "Off",
//																						"uiEvent": "Tree Off",
//																						"alpha": "1",
//																						"rotate": "0",
//																						"scale": "",
//																						"filter": "",
//																						"cursor": "",
//																						"zIndex": "0",
//																						"margin": "",
//																						"padding": "",
//																						"minW": "",
//																						"minH": "",
//																						"maxW": "",
//																						"maxH": "",
//																						"face": "",
//																						"styleClass": "",
//																						"background": "[42,124,255,1]",
//																						"border": "0",
//																						"borderStyle": "Solid",
//																						"borderColor": "[0,0,0,1.00]",
//																						"corner": "3",
//																						"shadow": "false",
//																						"shadowX": "2",
//																						"shadowY": "2",
//																						"shadowBlur": "3",
//																						"shadowSpread": "0",
//																						"shadowColor": "[0,0,0,0.50]"
//																					}
//																				},
//																				"subHuds": {
//																					"attrs": [
//																						{
//																							"type": "hudobj",
//																							"def": "text",
//																							"jaxId": "1GKJSP42P0",
//																							"attrs": {
//																								"properties": {
//																									"jaxId": "1GKJSP42P1",
//																									"attrs": {
//																										"type": "text",
//																										"id": "",
//																										"position": "Absolute",
//																										"x": "0",
//																										"y": "0",
//																										"w": "\"FW\"",
//																										"h": "\"FH\"",
//																										"anchorH": "Left",
//																										"anchorV": "Top",
//																										"autoLayout": "true",
//																										"display": "On",
//																										"clip": "Off",
//																										"uiEvent": "Tree Off",
//																										"alpha": "1",
//																										"rotate": "0",
//																										"scale": "",
//																										"filter": "",
//																										"cursor": "",
//																										"zIndex": "0",
//																										"margin": "",
//																										"padding": "",
//																										"minW": "",
//																										"minH": "",
//																										"maxW": "",
//																										"maxH": "",
//																										"face": "",
//																										"styleClass": "",
//																										"color": "[255,255,255]",
//																										"text": "Choose Universe Zip File",
//																										"font": "",
//																										"fontSize": "16",
//																										"bold": "false",
//																										"italic": "false",
//																										"underline": "false",
//																										"alignH": "Center",
//																										"alignV": "Center",
//																										"wrap": "false",
//																										"ellipsis": "false",
//																										"select": "false",
//																										"shadow": "false",
//																										"shadowX": "0",
//																										"shadowY": "2",
//																										"shadowBlur": "3",
//																										"shadowColor": "[0,0,0,1.00]",
//																										"shadowEx": "",
//																										"maxTextW": "0",
//																										"autoSizeW": "false",
//																										"autoSizeH": "false"
//																									}
//																								},
//																								"subHuds": {
//																									"attrs": []
//																								},
//																								"faces": {
//																									"jaxId": "1GKJSP42Q0",
//																									"attrs": {
//																										"1GKKF2JUU0": {
//																											"type": "hudface",
//																											"def": "HudFace",
//																											"jaxId": "1GKKF4F706",
//																											"attrs": {
//																												"properties": {
//																													"jaxId": "1GKKF4F707",
//																													"attrs": {}
//																												},
//																												"anis": {
//																													"attrs": []
//																												}
//																											},
//																											"faceTagId": "1GKKF2JUU0",
//																											"faceTagName": "file"
//																										}
//																									}
//																								},
//																								"functions": {
//																									"jaxId": "1GKJSP42Q1",
//																									"attrs": {}
//																								},
//																								"extraPpts": {
//																									"jaxId": "1GKJSP42Q2",
//																									"attrs": {}
//																								},
//																								"mockup": "false",
//																								"codes": "false",
//																								"locked": "false",
//																								"container": "false",
//																								"nameVal": "false"
//																							}
//																						}
//																					]
//																				},
//																				"faces": {
//																					"jaxId": "1GKJSP42Q3",
//																					"attrs": {
//																						"1GKKF2JUU0": {
//																							"type": "hudface",
//																							"def": "HudFace",
//																							"jaxId": "1GKKF4F7010",
//																							"attrs": {
//																								"properties": {
//																									"jaxId": "1GKKF4F7011",
//																									"attrs": {}
//																								},
//																								"anis": {
//																									"attrs": []
//																								}
//																							},
//																							"faceTagId": "1GKKF2JUU0",
//																							"faceTagName": "file"
//																						}
//																					}
//																				},
//																				"functions": {
//																					"jaxId": "1GKJSP42Q4",
//																					"attrs": {}
//																				},
//																				"extraPpts": {
//																					"jaxId": "1GKJSP42Q5",
//																					"attrs": {}
//																				},
//																				"mockup": "false",
//																				"codes": "false",
//																				"locked": "false",
//																				"container": "true",
//																				"nameVal": "false"
//																			}
//																		}
//																	]
//																},
//																"faces": {
//																	"jaxId": "1GKJSO0PG1",
//																	"attrs": {
//																		"1GKKF2JUU0": {
//																			"type": "hudface",
//																			"def": "HudFace",
//																			"jaxId": "1GKKF4F7014",
//																			"attrs": {
//																				"properties": {
//																					"jaxId": "1GKKF4F7015",
//																					"attrs": {}
//																				},
//																				"anis": {
//																					"attrs": []
//																				}
//																			},
//																			"faceTagId": "1GKKF2JUU0",
//																			"faceTagName": "file"
//																		}
//																	}
//																},
//																"functions": {
//																	"jaxId": "1GKJSO0PG2",
//																	"attrs": {}
//																},
//																"extraPpts": {
//																	"jaxId": "1GKJSO0PG3",
//																	"attrs": {}
//																},
//																"mockup": "false",
//																"codes": "true",
//																"locked": "false",
//																"container": "true",
//																"nameVal": "false"
//															}
//														}
//													]
//												},
//												"faces": {
//													"jaxId": "1GKJRQNAK2",
//													"attrs": {
//														"1GKKF1QFQ0": {
//															"type": "hudface",
//															"def": "HudFace",
//															"jaxId": "1GKKF4F7016",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKKF4F7017",
//																	"attrs": {
//																		"display": {
//																			"type": "choice",
//																			"valText": "Off"
//																		}
//																	}
//																},
//																"anis": {
//																	"attrs": []
//																}
//															},
//															"faceTagId": "1GKKF1QFQ0",
//															"faceTagName": "work"
//														},
//														"1GKKF2JUU0": {
//															"type": "hudface",
//															"def": "HudFace",
//															"jaxId": "1GKKF4F7018",
//															"attrs": {
//																"properties": {
//																	"jaxId": "1GKKF4F7019",
//																	"attrs": {
//																		"display": {
//																			"type": "choice",
//																			"valText": "On"
//																		}
//																	}
//																},
//																"anis": {
//																	"attrs": []
//																}
//															},
//															"faceTagId": "1GKKF2JUU0",
//															"faceTagName": "file"
//														}
//													}
//												},
//												"functions": {
//													"jaxId": "1GKJRQNAK3",
//													"attrs": {}
//												},
//												"extraPpts": {
//													"jaxId": "1GKJRQNAK4",
//													"attrs": {}
//												},
//												"mockup": "false",
//												"codes": "false",
//												"locked": "false",
//												"container": "true",
//												"nameVal": "false",
//												"exposeContainer": "false"
//											}
//										}
//									]
//								},
//								"faces": {
//									"jaxId": "1GFLUN3O65",
//									"attrs": {
//										"1GKKF2JUU0": {
//											"type": "hudface",
//											"def": "HudFace",
//											"jaxId": "1GKKF4F7022",
//											"attrs": {
//												"properties": {
//													"jaxId": "1GKKF4F7023",
//													"attrs": {}
//												},
//												"anis": {
//													"attrs": []
//												}
//											},
//											"faceTagId": "1GKKF2JUU0",
//											"faceTagName": "file"
//										}
//									}
//								},
//								"functions": {
//									"jaxId": "1GFLUN3O66",
//									"attrs": {}
//								},
//								"extraPpts": {
//									"jaxId": "1GFLUN3O67",
//									"attrs": {}
//								},
//								"mockup": "false",
//								"codes": "false",
//								"locked": "false",
//								"container": "true",
//								"nameVal": "false"
//							}
//						}
//					]
//				},
//				"faces": {
//					"jaxId": "1GFLQJK0E7",
//					"attrs": {
//						"1GKKF2JUU0": {
//							"type": "hudface",
//							"def": "HudFace",
//							"jaxId": "1GKKF4F7026",
//							"attrs": {
//								"properties": {
//									"jaxId": "1GKKF4F7027",
//									"attrs": {}
//								},
//								"anis": {
//									"attrs": []
//								}
//							},
//							"faceTagId": "1GKKF2JUU0",
//							"faceTagName": "file"
//						}
//					}
//				},
//				"functions": {
//					"jaxId": "1GFLQJK0E8",
//					"attrs": {}
//				},
//				"extraPpts": {
//					"jaxId": "1GFLQJK0E9",
//					"attrs": {}
//				},
//				"mockup": "false",
//				"codes": "false",
//				"locked": "false",
//				"container": "true",
//				"nameVal": "false"
//			}
//		},
//		"exposeGear": "false",
//		"exposeTemplate": "false",
//		"exposeAttrs": {
//			"type": "object",
//			"def": "exposeAttrs",
//			"jaxId": "1GFLQJK0E10",
//			"attrs": {
//				"id": "true",
//				"position": "true",
//				"x": "true",
//				"y": "true",
//				"w": "false",
//				"h": "false",
//				"anchorH": "false",
//				"anchorV": "false",
//				"autoLayout": "false",
//				"display": "true",
//				"contentLayout": "false",
//				"subAlign": "false",
//				"itemsAlign": "false",
//				"itemsWrap": "false",
//				"clip": "false",
//				"uiEvent": "false",
//				"alpha": "false",
//				"rotate": "false",
//				"scale": "false",
//				"filter": "false",
//				"aspect": "false",
//				"cursor": "false",
//				"zIndex": "false",
//				"flex": "false",
//				"margin": "false",
//				"traceSize": "false",
//				"padding": "false",
//				"minW": "false",
//				"minH": "false",
//				"maxW": "false",
//				"maxH": "false",
//				"styleClass": "false",
//				"innerLayout": {
//					"valText": "false"
//				},
//				"marginL": {
//					"valText": "false"
//				},
//				"marginR": {
//					"valText": "false"
//				},
//				"marginT": {
//					"valText": "false"
//				},
//				"marginB": {
//					"valText": "false"
//				},
//				"paddingL": {
//					"valText": "false"
//				},
//				"paddingR": {
//					"valText": "false"
//				},
//				"paddingT": {
//					"valText": "false"
//				},
//				"paddingB": {
//					"valText": "false"
//				},
//				"attach": {
//					"valText": "false"
//				}
//			}
//		},
//		"exposeStateAttrs": {
//			"type": "array",
//			"def": "StringArray",
//			"attrs": []
//		}
//	}
//}

//Auto genterated by Cody
/*}#MoreImports*/
/*#{StartApp*/
tabOS.heartBeat=false;
/*}#StartApp*/
//----------------------------------------------------------------------------
//Start the app:
async function startApp() {
	/*#{AppCode*/
	let app,uiDef;
	
	document.title="Setup Tab-OS";
	window.tabOSApp=app=await VFACT.createApp();
	uiDef=MainUI(app);
	//init app, create app UI tree:
	await VFACT.initApp(app,uiDef,{
		wait:1
	});
	/*}#AppCode*/
}
tabOS.setup().then(()=>{startApp();});

/*#{EndDoc*/
/*}#EndDoc*/

/*Cody Project Doc*/
//{
//	"type": "docfile",
//	"def": "app",
//	"jaxId": "1GFLQHQEA0",
//	"editVersion": 22,
//	"attrs": {
//		"fonts": {
//			"type": "object",
//			"def": "Fonts",
//			"jaxId": "1GFLQHQEA1",
//			"editVersion": 0,
//			"attrs": {}
//		},
//		"exportTarget": "VFACT document",
//		"bgColor": "[255,255,255]",
//		"multiTouch": "false",
//		"camera": "false",
//		"notification": "false",
//		"contacts": "false"
//	}
//}

</script>
</body>
</html>
